diff options
Diffstat (limited to 'spec')
519 files changed, 11167 insertions, 4678 deletions
diff --git a/spec/controllers/abuse_reports_controller_spec.rb b/spec/controllers/abuse_reports_controller_spec.rb index ada011e7595..7104305e9d2 100644 --- a/spec/controllers/abuse_reports_controller_spec.rb +++ b/spec/controllers/abuse_reports_controller_spec.rb @@ -19,7 +19,7 @@ describe AbuseReportsController do user_id = user.id user.destroy - get :new, { user_id: user_id } + get :new, params: { user_id: user_id } expect(response).to redirect_to root_path expect(flash[:alert]).to eq('Cannot create the abuse report. The user has been deleted.') @@ -30,7 +30,7 @@ describe AbuseReportsController do it 'redirects the reporter to the user\'s profile' do user.block - get :new, { user_id: user.id } + get :new, params: { user_id: user.id } expect(response).to redirect_to user expect(flash[:alert]).to eq('Cannot create the abuse report. This user has been blocked.') @@ -42,18 +42,18 @@ describe AbuseReportsController do context 'with valid attributes' do it 'saves the abuse report' do expect do - post :create, abuse_report: attrs + post :create, params: { abuse_report: attrs } end.to change { AbuseReport.count }.by(1) end it 'calls notify' do expect_any_instance_of(AbuseReport).to receive(:notify) - post :create, abuse_report: attrs + post :create, params: { abuse_report: attrs } end it 'redirects back to the reported user' do - post :create, abuse_report: attrs + post :create, params: { abuse_report: attrs } expect(response).to redirect_to user end @@ -62,7 +62,7 @@ describe AbuseReportsController do context 'with invalid attributes' do it 'renders new' do attrs.delete(:user_id) - post :create, abuse_report: attrs + post :create, params: { abuse_report: attrs } expect(response).to render_template(:new) end diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb index 2e0f79cd313..9af472df74e 100644 --- a/spec/controllers/admin/application_settings_controller_spec.rb +++ b/spec/controllers/admin/application_settings_controller_spec.rb @@ -52,35 +52,35 @@ describe Admin::ApplicationSettingsController do end it 'updates the password_authentication_enabled_for_git setting' do - put :update, application_setting: { password_authentication_enabled_for_git: "0" } + put :update, params: { application_setting: { password_authentication_enabled_for_git: "0" } } expect(response).to redirect_to(admin_application_settings_path) expect(ApplicationSetting.current.password_authentication_enabled_for_git).to eq(false) end it 'updates the default_project_visibility for string value' do - put :update, application_setting: { default_project_visibility: "20" } + put :update, params: { application_setting: { default_project_visibility: "20" } } expect(response).to redirect_to(admin_application_settings_path) expect(ApplicationSetting.current.default_project_visibility).to eq(Gitlab::VisibilityLevel::PUBLIC) end it 'update the restricted levels for string values' do - put :update, application_setting: { restricted_visibility_levels: %w[10 20] } + put :update, params: { application_setting: { restricted_visibility_levels: %w[10 20] } } expect(response).to redirect_to(admin_application_settings_path) expect(ApplicationSetting.current.restricted_visibility_levels).to eq([10, 20]) end it 'updates the restricted_visibility_levels when empty array is passed' do - put :update, application_setting: { restricted_visibility_levels: [""] } + put :update, params: { application_setting: { restricted_visibility_levels: [""] } } expect(response).to redirect_to(admin_application_settings_path) expect(ApplicationSetting.current.restricted_visibility_levels).to be_empty end it 'updates the receive_max_input_size setting' do - put :update, application_setting: { receive_max_input_size: "1024" } + put :update, params: { application_setting: { receive_max_input_size: "1024" } } expect(response).to redirect_to(admin_application_settings_path) expect(ApplicationSetting.current.receive_max_input_size).to eq(1024) diff --git a/spec/controllers/admin/applications_controller_spec.rb b/spec/controllers/admin/applications_controller_spec.rb index 7bd6c0e6117..7e1ce70dc7d 100644 --- a/spec/controllers/admin/applications_controller_spec.rb +++ b/spec/controllers/admin/applications_controller_spec.rb @@ -19,7 +19,7 @@ describe Admin::ApplicationsController do describe 'GET #edit' do it 'renders the application form' do - get :edit, id: application.id + get :edit, params: { id: application.id } expect(response).to render_template :edit expect(assigns[:scopes]).to be_kind_of(Doorkeeper::OAuth::Scopes) @@ -31,7 +31,7 @@ describe Admin::ApplicationsController do create_params = attributes_for(:application, trusted: true) expect do - post :create, doorkeeper_application: create_params + post :create, params: { doorkeeper_application: create_params } end.to change { Doorkeeper::Application.count }.by(1) application = Doorkeeper::Application.last @@ -42,7 +42,7 @@ describe Admin::ApplicationsController do it 'renders the application form on errors' do expect do - post :create, doorkeeper_application: attributes_for(:application).merge(redirect_uri: nil) + post :create, params: { doorkeeper_application: attributes_for(:application).merge(redirect_uri: nil) } end.not_to change { Doorkeeper::Application.count } expect(response).to render_template :new @@ -52,7 +52,7 @@ describe Admin::ApplicationsController do describe 'PATCH #update' do it 'updates the application' do - patch :update, id: application.id, doorkeeper_application: { redirect_uri: 'http://example.com/', trusted: true } + patch :update, params: { id: application.id, doorkeeper_application: { redirect_uri: 'http://example.com/', trusted: true } } application.reload @@ -61,7 +61,7 @@ describe Admin::ApplicationsController do end it 'renders the application form on errors' do - patch :update, id: application.id, doorkeeper_application: { redirect_uri: nil } + patch :update, params: { id: application.id, doorkeeper_application: { redirect_uri: nil } } expect(response).to render_template :edit expect(assigns[:scopes]).to be_kind_of(Doorkeeper::OAuth::Scopes) diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb index 0dad95e418f..647fce0ecef 100644 --- a/spec/controllers/admin/groups_controller_spec.rb +++ b/spec/controllers/admin/groups_controller_spec.rb @@ -12,12 +12,12 @@ describe Admin::GroupsController do describe 'DELETE #destroy' do it 'schedules a group destroy' do Sidekiq::Testing.fake! do - expect { delete :destroy, id: project.group.path }.to change(GroupDestroyWorker.jobs, :size).by(1) + expect { delete :destroy, params: { id: project.group.path } }.to change(GroupDestroyWorker.jobs, :size).by(1) end end it 'redirects to the admin group path' do - delete :destroy, id: project.group.path + delete :destroy, params: { id: project.group.path } expect(response).to redirect_to(admin_groups_path) end @@ -27,9 +27,11 @@ describe Admin::GroupsController do let(:group_user) { create(:user) } it 'adds user to members' do - put :members_update, id: group, - user_ids: group_user.id, - access_level: Gitlab::Access::GUEST + put :members_update, params: { + id: group, + user_ids: group_user.id, + access_level: Gitlab::Access::GUEST + } expect(response).to set_flash.to 'Users were successfully added.' expect(response).to redirect_to(admin_group_path(group)) @@ -37,18 +39,22 @@ describe Admin::GroupsController do end it 'can add unlimited members' do - put :members_update, id: group, - user_ids: 1.upto(1000).to_a.join(','), - access_level: Gitlab::Access::GUEST + put :members_update, params: { + id: group, + user_ids: 1.upto(1000).to_a.join(','), + access_level: Gitlab::Access::GUEST + } expect(response).to set_flash.to 'Users were successfully added.' expect(response).to redirect_to(admin_group_path(group)) end it 'adds no user to members' do - put :members_update, id: group, - user_ids: '', - access_level: Gitlab::Access::GUEST + put :members_update, params: { + id: group, + user_ids: '', + access_level: Gitlab::Access::GUEST + } expect(response).to set_flash.to 'No users specified.' expect(response).to redirect_to(admin_group_path(group)) diff --git a/spec/controllers/admin/hooks_controller_spec.rb b/spec/controllers/admin/hooks_controller_spec.rb index d2c1e634930..9bc58344e4e 100644 --- a/spec/controllers/admin/hooks_controller_spec.rb +++ b/spec/controllers/admin/hooks_controller_spec.rb @@ -20,7 +20,7 @@ describe Admin::HooksController do merge_requests_events: true } - post :create, hook: hook_params + post :create, params: { hook: hook_params } expect(response).to have_gitlab_http_status(302) expect(SystemHook.all.size).to eq(1) diff --git a/spec/controllers/admin/identities_controller_spec.rb b/spec/controllers/admin/identities_controller_spec.rb index a29853bf8df..e5428c8ddeb 100644 --- a/spec/controllers/admin/identities_controller_spec.rb +++ b/spec/controllers/admin/identities_controller_spec.rb @@ -13,7 +13,7 @@ describe Admin::IdentitiesController do it 'repairs ldap blocks' do expect_any_instance_of(RepairLdapBlockedUserService).to receive(:execute) - put :update, user_id: user.username, id: user.ldap_identity.id, identity: { provider: 'twitter' } + put :update, params: { user_id: user.username, id: user.ldap_identity.id, identity: { provider: 'twitter' } } end end @@ -23,7 +23,7 @@ describe Admin::IdentitiesController do it 'repairs ldap blocks' do expect_any_instance_of(RepairLdapBlockedUserService).to receive(:execute) - delete :destroy, user_id: user.username, id: user.ldap_identity.id + delete :destroy, params: { user_id: user.username, id: user.ldap_identity.id } end end end diff --git a/spec/controllers/admin/projects_controller_spec.rb b/spec/controllers/admin/projects_controller_spec.rb index ee1aff09bdf..8166657f674 100644 --- a/spec/controllers/admin/projects_controller_spec.rb +++ b/spec/controllers/admin/projects_controller_spec.rb @@ -11,13 +11,13 @@ describe Admin::ProjectsController do render_views it 'retrieves the project for the given visibility level' do - get :index, visibility_level: [Gitlab::VisibilityLevel::PUBLIC] + get :index, params: { visibility_level: [Gitlab::VisibilityLevel::PUBLIC] } expect(response.body).to match(project.name) end it 'does not retrieve the project' do - get :index, visibility_level: [Gitlab::VisibilityLevel::INTERNAL] + get :index, params: { visibility_level: [Gitlab::VisibilityLevel::INTERNAL] } expect(response.body).not_to match(project.name) end @@ -47,7 +47,7 @@ describe Admin::ProjectsController do render_views it 'renders show page' do - get :show, namespace_id: project.namespace.path, id: project.path + get :show, params: { namespace_id: project.namespace.path, id: project.path } expect(response).to have_gitlab_http_status(200) expect(response.body).to match(project.name) diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb index 312dbdd0624..4cf14030ca1 100644 --- a/spec/controllers/admin/runners_controller_spec.rb +++ b/spec/controllers/admin/runners_controller_spec.rb @@ -17,13 +17,13 @@ describe Admin::RunnersController do describe '#show' do it 'shows a particular runner' do - get :show, id: runner.id + get :show, params: { id: runner.id } expect(response).to have_gitlab_http_status(200) end it 'shows 404 for unknown runner' do - get :show, id: 0 + get :show, params: { id: 0 } expect(response).to have_gitlab_http_status(404) end @@ -34,7 +34,7 @@ describe Admin::RunnersController do new_desc = runner.description.swapcase expect do - post :update, id: runner.id, runner: { description: new_desc } + post :update, params: { id: runner.id, runner: { description: new_desc } } end.to change { runner.ensure_runner_queue_value } runner.reload @@ -46,7 +46,7 @@ describe Admin::RunnersController do describe '#destroy' do it 'destroys the runner' do - delete :destroy, id: runner.id + delete :destroy, params: { id: runner.id } expect(response).to have_gitlab_http_status(302) expect(Ci::Runner.find_by(id: runner.id)).to be_nil @@ -58,7 +58,7 @@ describe Admin::RunnersController do runner.update(active: false) expect do - post :resume, id: runner.id + post :resume, params: { id: runner.id } end.to change { runner.ensure_runner_queue_value } runner.reload @@ -73,7 +73,7 @@ describe Admin::RunnersController do runner.update(active: true) expect do - post :pause, id: runner.id + post :pause, params: { id: runner.id } end.to change { runner.ensure_runner_queue_value } runner.reload diff --git a/spec/controllers/admin/services_controller_spec.rb b/spec/controllers/admin/services_controller_spec.rb index 4439ea4a533..ec161b92245 100644 --- a/spec/controllers/admin/services_controller_spec.rb +++ b/spec/controllers/admin/services_controller_spec.rb @@ -18,7 +18,7 @@ describe Admin::ServicesController do end it 'successfully displays the template' do - get :edit, id: service.id + get :edit, params: { id: service.id } expect(response).to have_gitlab_http_status(200) end @@ -44,7 +44,7 @@ describe Admin::ServicesController do it 'calls the propagation worker when service is active' do expect(PropagateServiceTemplateWorker).to receive(:perform_async).with(service.id) - put :update, id: service.id, service: { active: true } + put :update, params: { id: service.id, service: { active: true } } expect(response).to have_gitlab_http_status(302) end @@ -52,7 +52,7 @@ describe Admin::ServicesController do it 'does not call the propagation worker when service is not active' do expect(PropagateServiceTemplateWorker).not_to receive(:perform_async) - put :update, id: service.id, service: { properties: {} } + put :update, params: { id: service.id, service: { properties: {} } } expect(response).to have_gitlab_http_status(302) end diff --git a/spec/controllers/admin/spam_logs_controller_spec.rb b/spec/controllers/admin/spam_logs_controller_spec.rb index 7a96ef6a5cc..2b946ec1c68 100644 --- a/spec/controllers/admin/spam_logs_controller_spec.rb +++ b/spec/controllers/admin/spam_logs_controller_spec.rb @@ -20,13 +20,13 @@ describe Admin::SpamLogsController do describe '#destroy' do it 'removes only the spam log when removing log' do - expect { delete :destroy, id: first_spam.id }.to change { SpamLog.count }.by(-1) + expect { delete :destroy, params: { id: first_spam.id } }.to change { SpamLog.count }.by(-1) expect(User.find(user.id)).to be_truthy expect(response).to have_gitlab_http_status(200) end it 'removes user and his spam logs when removing the user' do - delete :destroy, id: first_spam.id, remove_user: true + delete :destroy, params: { id: first_spam.id, remove_user: true } expect(flash[:notice]).to eq "User #{user.username} was successfully removed." expect(response).to have_gitlab_http_status(302) @@ -40,7 +40,7 @@ describe Admin::SpamLogsController do allow_any_instance_of(AkismetService).to receive(:submit_ham).and_return(true) end it 'submits the log as ham' do - post :mark_as_ham, id: first_spam.id + post :mark_as_ham, params: { id: first_spam.id } expect(response).to have_gitlab_http_status(302) expect(SpamLog.find(first_spam.id).submitted_as_ham).to be_truthy diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 3dd0b2623ac..6b66cbd2651 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -17,7 +17,7 @@ describe Admin::UsersController do end it 'deletes user and ghosts their contributions' do - delete :destroy, id: user.username, format: :json + delete :destroy, params: { id: user.username }, format: :json expect(response).to have_gitlab_http_status(200) expect(User.exists?(user.id)).to be_falsy @@ -25,7 +25,7 @@ describe Admin::UsersController do end it 'deletes the user and their contributions when hard delete is specified' do - delete :destroy, id: user.username, hard_delete: true, format: :json + delete :destroy, params: { id: user.username, hard_delete: true }, format: :json expect(response).to have_gitlab_http_status(200) expect(User.exists?(user.id)).to be_falsy @@ -35,7 +35,7 @@ describe Admin::UsersController do describe 'PUT block/:id' do it 'blocks user' do - put :block, id: user.username + put :block, params: { id: user.username } user.reload expect(user.blocked?).to be_truthy expect(flash[:notice]).to eq 'Successfully blocked' @@ -51,7 +51,7 @@ describe Admin::UsersController do end it 'does not unblock user' do - put :unblock, id: user.username + put :unblock, params: { id: user.username } user.reload expect(user.blocked?).to be_truthy expect(flash[:alert]).to eq 'This user cannot be unlocked manually from GitLab' @@ -64,7 +64,7 @@ describe Admin::UsersController do end it 'unblocks user' do - put :unblock, id: user.username + put :unblock, params: { id: user.username } user.reload expect(user.blocked?).to be_falsey expect(flash[:notice]).to eq 'Successfully unblocked' @@ -79,7 +79,7 @@ describe Admin::UsersController do end it 'unlocks user' do - put :unlock, id: user.username + put :unlock, params: { id: user.username } user.reload expect(user.access_locked?).to be_falsey end @@ -93,7 +93,7 @@ describe Admin::UsersController do end it 'confirms user' do - put :confirm, id: user.username + put :confirm, params: { id: user.username } user.reload expect(user.confirmed?).to be_truthy end @@ -121,17 +121,17 @@ describe Admin::UsersController do end def go - patch :disable_two_factor, id: user.to_param + patch :disable_two_factor, params: { id: user.to_param } end end describe 'POST create' do it 'creates the user' do - expect { post :create, user: attributes_for(:user) }.to change { User.count }.by(1) + expect { post :create, params: { user: attributes_for(:user) } }.to change { User.count }.by(1) end it 'shows only one error message for an invalid email' do - post :create, user: attributes_for(:user, email: 'bogus') + post :create, params: { user: attributes_for(:user, email: 'bogus') } expect(assigns[:user].errors).to contain_exactly("Email is invalid") end end @@ -147,7 +147,7 @@ describe Admin::UsersController do } } - post :update, params + post :update, params: params end context 'when the admin changes his own password' do @@ -227,13 +227,13 @@ describe Admin::UsersController do end it "shows a notice" do - post :impersonate, id: user.username + post :impersonate, params: { id: user.username } expect(flash[:alert]).to eq("You cannot impersonate a blocked user") end it "doesn't sign us in as the user" do - post :impersonate, id: user.username + post :impersonate, params: { id: user.username } expect(warden.user).to eq(admin) end @@ -241,25 +241,25 @@ describe Admin::UsersController do context "when the user is not blocked" do it "stores the impersonator in the session" do - post :impersonate, id: user.username + post :impersonate, params: { id: user.username } expect(session[:impersonator_id]).to eq(admin.id) end it "signs us in as the user" do - post :impersonate, id: user.username + post :impersonate, params: { id: user.username } expect(warden.user).to eq(user) end it "redirects to root" do - post :impersonate, id: user.username + post :impersonate, params: { id: user.username } expect(response).to redirect_to(root_path) end it "shows a notice" do - post :impersonate, id: user.username + post :impersonate, params: { id: user.username } expect(flash[:alert]).to eq("You are now impersonating #{user.username}") end @@ -271,7 +271,7 @@ describe Admin::UsersController do end it "shows error page" do - post :impersonate, id: user.username + post :impersonate, params: { id: user.username } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index c2bd7fd9808..43f561f7a25 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -522,13 +522,13 @@ describe ApplicationController do end it 'renders a 403 when a message is passed to access denied' do - get :index, message: 'None shall pass' + get :index, params: { message: 'None shall pass' } expect(response).to have_gitlab_http_status(403) end it 'renders a status passed to access denied' do - get :index, status: 401 + get :index, params: { status: 401 } expect(response).to have_gitlab_http_status(401) end @@ -548,34 +548,18 @@ describe ApplicationController do end context 'html' do - subject { get :index, text: "hi \255" } + subject { get :index, params: { text: "hi \255" } } it 'renders 412' do - if Gitlab.rails5? - expect { subject }.to raise_error(ActionController::BadRequest) - else - subject - - expect(response).to have_gitlab_http_status(412) - expect(response).to render_template :precondition_failed - end + expect { subject }.to raise_error(ActionController::BadRequest) end end context 'js' do - subject { get :index, text: "hi \255", format: :js } + subject { get :index, format: :js, params: { text: "hi \255" } } it 'renders 412' do - if Gitlab.rails5? - expect { subject }.to raise_error(ActionController::BadRequest) - else - subject - - json_response = JSON.parse(response.body) - - expect(response).to have_gitlab_http_status(412) - expect(json_response['error']).to eq('Invalid UTF-8') - end + expect { subject }.to raise_error(ActionController::BadRequest) end end end diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb index 883bb35f396..4458a7223bf 100644 --- a/spec/controllers/autocomplete_controller_spec.rb +++ b/spec/controllers/autocomplete_controller_spec.rb @@ -15,7 +15,7 @@ describe AutocompleteController do describe 'GET #users with project ID' do before do - get(:users, project_id: project.id) + get(:users, params: { project_id: project.id }) end it 'returns the project members' do @@ -27,7 +27,7 @@ describe AutocompleteController do describe 'GET #users with unknown project' do before do - get(:users, project_id: 'unknown') + get(:users, params: { project_id: 'unknown' }) end it { expect(response).to have_gitlab_http_status(404) } @@ -44,7 +44,7 @@ describe AutocompleteController do describe 'GET #users with group ID' do before do - get(:users, group_id: group.id) + get(:users, params: { group_id: group.id }) end it 'returns the group members' do @@ -56,7 +56,7 @@ describe AutocompleteController do describe 'GET #users with unknown group ID' do before do - get(:users, group_id: 'unknown') + get(:users, params: { group_id: 'unknown' }) end it { expect(response).to have_gitlab_http_status(404) } @@ -72,7 +72,7 @@ describe AutocompleteController do describe 'GET #users with project ID' do before do - get(:users, project_id: project.id, current_user: true) + get(:users, params: { project_id: project.id, current_user: true }) end it 'returns the project members and non-members' do @@ -100,7 +100,7 @@ describe AutocompleteController do user1 = create(:user, username: 'user1', name: 'Ian') sign_in(user) - get(:users, search: 'user') + get(:users, params: { search: 'user' }) response_usernames = json_response.map { |user| user['username'] } @@ -128,7 +128,7 @@ describe AutocompleteController do describe 'GET #users with public project' do before do public_project.add_guest(user) - get(:users, project_id: public_project.id) + get(:users, params: { project_id: public_project.id }) end it { expect(json_response).to be_kind_of(Array) } @@ -137,7 +137,7 @@ describe AutocompleteController do describe 'GET #users with project' do before do - get(:users, project_id: project.id) + get(:users, params: { project_id: project.id }) end it { expect(response).to have_gitlab_http_status(404) } @@ -145,7 +145,7 @@ describe AutocompleteController do describe 'GET #users with unknown project' do before do - get(:users, project_id: 'unknown') + get(:users, params: { project_id: 'unknown' }) end it { expect(response).to have_gitlab_http_status(404) } @@ -154,7 +154,7 @@ describe AutocompleteController do describe 'GET #users with inaccessible group' do before do project.add_guest(user) - get(:users, group_id: user.namespace.id) + get(:users, params: { group_id: user.namespace.id }) end it { expect(response).to have_gitlab_http_status(404) } @@ -171,7 +171,7 @@ describe AutocompleteController do describe 'GET #users with todo filter' do it 'gives an array of users' do - get :users, todo_filter: true + get :users, params: { todo_filter: true } expect(response.status).to eq 200 expect(json_response).to be_kind_of(Array) @@ -186,13 +186,13 @@ describe AutocompleteController do end it 'includes the author' do - get(:users, author_id: non_member.id) + get(:users, params: { author_id: non_member.id }) expect(json_response.first["username"]).to eq non_member.username end it 'rejects non existent user ids' do - get(:users, author_id: 99999) + get(:users, params: { author_id: 99999 }) expect(json_response.collect { |u| u['id'] }).not_to include(99999) end @@ -200,7 +200,7 @@ describe AutocompleteController do context 'without authenticating' do it 'returns empty result' do - get(:users, author_id: non_member.id) + get(:users, params: { author_id: non_member.id }) expect(json_response).to be_empty end @@ -213,7 +213,7 @@ describe AutocompleteController do end it 'skips the user IDs passed' do - get(:users, skip_users: [user, user2].map(&:id)) + get(:users, params: { skip_users: [user, user2].map(&:id) }) response_user_ids = json_response.map { |user| user['id'] } @@ -238,7 +238,7 @@ describe AutocompleteController do describe 'GET #projects with project ID' do before do - get(:projects, project_id: project.id) + get(:projects, params: { project_id: project.id }) end it 'returns projects' do @@ -259,7 +259,7 @@ describe AutocompleteController do describe 'GET #projects with project ID and search' do before do - get(:projects, project_id: project.id, search: 'rugged') + get(:projects, params: { project_id: project.id, search: 'rugged' }) end it 'returns projects' do @@ -283,7 +283,7 @@ describe AutocompleteController do describe 'GET #projects with project ID' do before do - get(:projects, project_id: project.id) + get(:projects, params: { project_id: project.id }) end it 'returns projects' do @@ -305,7 +305,7 @@ describe AutocompleteController do describe 'GET #projects with project ID and offset_id' do before do - get(:projects, project_id: project.id, offset_id: authorized_project.id) + get(:projects, params: { project_id: project.id, offset_id: authorized_project.id }) end it 'returns projects' do @@ -324,7 +324,7 @@ describe AutocompleteController do describe 'GET #projects with project ID' do before do - get(:projects, project_id: project.id) + get(:projects, params: { project_id: project.id }) end it 'returns no projects' do diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb index 6d0483f0032..8657fc2ebc0 100644 --- a/spec/controllers/boards/issues_controller_spec.rb +++ b/spec/controllers/boards/issues_controller_spec.rb @@ -153,7 +153,7 @@ describe Boards::IssuesController do params[:project_id] = project end - get :index, params.compact + get :index, params: params.compact end end @@ -230,9 +230,11 @@ describe Boards::IssuesController do def create_issue(user:, board:, list:, title:) sign_in(user) - post :create, board_id: board.to_param, - list_id: list.to_param, - issue: { title: title, project_id: project.id }, + post :create, params: { + board_id: board.to_param, + list_id: list.to_param, + issue: { title: title, project_id: project.id } + }, format: :json end end @@ -291,12 +293,14 @@ describe Boards::IssuesController do def move(user:, board:, issue:, from_list_id:, to_list_id:) sign_in(user) - patch :update, namespace_id: project.namespace.to_param, - project_id: project.id, - board_id: board.to_param, - id: issue.id, - from_list_id: from_list_id, - to_list_id: to_list_id, + patch :update, params: { + namespace_id: project.namespace.to_param, + project_id: project.id, + board_id: board.to_param, + id: issue.id, + from_list_id: from_list_id, + to_list_id: to_list_id + }, format: :json end end diff --git a/spec/controllers/boards/lists_controller_spec.rb b/spec/controllers/boards/lists_controller_spec.rb index 80631d2efb0..70033857168 100644 --- a/spec/controllers/boards/lists_controller_spec.rb +++ b/spec/controllers/boards/lists_controller_spec.rb @@ -46,9 +46,11 @@ describe Boards::ListsController do def read_board_list(user:, board:) sign_in(user) - get :index, namespace_id: project.namespace.to_param, - project_id: project, - board_id: board.to_param, + get :index, params: { + namespace_id: project.namespace.to_param, + project_id: project, + board_id: board.to_param + }, format: :json end end @@ -103,10 +105,12 @@ describe Boards::ListsController do def create_board_list(user:, board:, label_id:) sign_in(user) - post :create, namespace_id: project.namespace.to_param, - project_id: project, - board_id: board.to_param, - list: { label_id: label_id }, + post :create, params: { + namespace_id: project.namespace.to_param, + project_id: project, + board_id: board.to_param, + list: { label_id: label_id } + }, format: :json end end @@ -163,11 +167,7 @@ describe Boards::ListsController do list: { position: position }, format: :json } - if Gitlab.rails5? - patch :update, params: params, as: :json - else - patch :update, params - end + patch :update, params: params, as: :json end end @@ -205,10 +205,12 @@ describe Boards::ListsController do def remove_board_list(user:, board:, list:) sign_in(user) - delete :destroy, namespace_id: project.namespace.to_param, - project_id: project, - board_id: board.to_param, - id: list.to_param, + delete :destroy, params: { + namespace_id: project.namespace.to_param, + project_id: project, + board_id: board.to_param, + id: list.to_param + }, format: :json end end @@ -249,9 +251,11 @@ describe Boards::ListsController do def generate_default_lists(user:, board:) sign_in(user) - post :generate, namespace_id: project.namespace.to_param, - project_id: project, - board_id: board.to_param, + post :generate, params: { + namespace_id: project.namespace.to_param, + project_id: project, + board_id: board.to_param + }, format: :json end end diff --git a/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb b/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb index 3c9452cc42a..9b2d054f4fc 100644 --- a/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb +++ b/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb @@ -70,7 +70,7 @@ describe ControllerWithCrossProjectAccessCheck do end it 'correctly renders an action that does not require cross project access' do - get :show, id: 'nothing' + get :show, params: { id: 'nothing' } expect(response).to have_gitlab_http_status(200) end @@ -131,13 +131,13 @@ describe ControllerWithCrossProjectAccessCheck do end it 'does not skip the check on an action that is not skipped' do - get :show, id: 'hello' + get :show, params: { id: 'hello' } expect(response).to have_gitlab_http_status(403) end it 'does not skip the check on an action that was not defined to skip' do - get :edit, id: 'hello' + get :edit, params: { id: 'hello' } expect(response).to have_gitlab_http_status(403) end diff --git a/spec/controllers/concerns/group_tree_spec.rb b/spec/controllers/concerns/group_tree_spec.rb index 503eb416962..9fe17210d50 100644 --- a/spec/controllers/concerns/group_tree_spec.rb +++ b/spec/controllers/concerns/group_tree_spec.rb @@ -23,7 +23,7 @@ describe GroupTree do other_group = create(:group, name: 'filter') other_group.add_owner(user) - get :index, filter: 'filt', format: :json + get :index, params: { filter: 'filt' }, format: :json expect(assigns(:groups)).to contain_exactly(other_group) end @@ -40,7 +40,7 @@ describe GroupTree do it 'contains only the subgroup when a parent was given' do subgroup = create(:group, :public, parent: group) - get :index, parent_id: group.id, format: :json + get :index, params: { parent_id: group.id }, format: :json expect(assigns(:groups)).to contain_exactly(subgroup) end @@ -48,7 +48,7 @@ describe GroupTree do it 'allows filtering for subgroups and includes the parents for rendering' do subgroup = create(:group, :public, parent: group, name: 'filter') - get :index, filter: 'filt', format: :json + get :index, params: { filter: 'filt' }, format: :json expect(assigns(:groups)).to contain_exactly(group, subgroup) end @@ -59,7 +59,7 @@ describe GroupTree do subgroup.add_developer(user) _other_subgroup = create(:group, :private, parent: parent, name: 'filte') - get :index, filter: 'filt', format: :json + get :index, params: { filter: 'filt' }, format: :json expect(assigns(:groups)).to contain_exactly(parent, subgroup) end @@ -70,7 +70,7 @@ describe GroupTree do subgroup = create(:group, :public, parent: group) search_result = create(:group, :public, name: 'result', parent: subgroup) - get :index, filter: 'resu', format: :json + get :index, params: { filter: 'resu' }, format: :json expect(assigns(:groups)).to contain_exactly(group, subgroup, search_result) end @@ -87,7 +87,7 @@ describe GroupTree do it 'expands the tree when filtering' do subgroup = create(:group, :public, parent: group, name: 'filter') - get :index, filter: 'filt', format: :json + get :index, params: { filter: 'filt' }, format: :json children_response = json_response.first['children'] diff --git a/spec/controllers/concerns/issuable_collections_spec.rb b/spec/controllers/concerns/issuable_collections_spec.rb index f87eed6ff9f..5a3a7a15f5a 100644 --- a/spec/controllers/concerns/issuable_collections_spec.rb +++ b/spec/controllers/concerns/issuable_collections_spec.rb @@ -90,7 +90,7 @@ describe IssuableCollections do finder_options = controller.send(:finder_options) - expect(finder_options).to eq({ + expect(finder_options).to eq(ActionController::Parameters.new({ 'assignee_id' => '1', 'assignee_username' => 'user1', 'author_id' => '2', @@ -103,7 +103,7 @@ describe IssuableCollections do 'search' => 'baz', 'sort' => 'priority', 'state' => 'opened' - }) + }).permit!) end end end diff --git a/spec/controllers/concerns/lfs_request_spec.rb b/spec/controllers/concerns/lfs_request_spec.rb index 76c878ec5d7..7b49d4b6a3a 100644 --- a/spec/controllers/concerns/lfs_request_spec.rb +++ b/spec/controllers/concerns/lfs_request_spec.rb @@ -34,7 +34,7 @@ describe LfsRequest do describe '#storage_project' do it 'assigns the project as storage project' do - get :show, id: project.id + get :show, params: { id: project.id } expect(assigns(:storage_project)).to eq(project) end @@ -42,7 +42,7 @@ describe LfsRequest do it 'assigns the source of a forked project' do forked_project = fork_project(project) - get :show, id: forked_project.id + get :show, params: { id: forked_project.id } expect(assigns(:storage_project)).to eq(project) end diff --git a/spec/controllers/dashboard/groups_controller_spec.rb b/spec/controllers/dashboard/groups_controller_spec.rb index 9068c1a792e..c8d99f79277 100644 --- a/spec/controllers/dashboard/groups_controller_spec.rb +++ b/spec/controllers/dashboard/groups_controller_spec.rb @@ -33,7 +33,7 @@ describe Dashboard::GroupsController do end it 'renders only groups the user is a member of when searching hierarchy correctly' do - get :index, filter: 'chef', format: :json + get :index, params: { filter: 'chef' }, format: :json expect(response).to have_gitlab_http_status(200) all_groups = [top_level_result, top_level_a, sub_level_result_a] diff --git a/spec/controllers/dashboard/milestones_controller_spec.rb b/spec/controllers/dashboard/milestones_controller_spec.rb index 278b980b6d8..8a8cc14fd4c 100644 --- a/spec/controllers/dashboard/milestones_controller_spec.rb +++ b/spec/controllers/dashboard/milestones_controller_spec.rb @@ -34,7 +34,7 @@ describe Dashboard::MilestonesController do render_views def view_milestone - get :show, id: milestone.safe_title, title: milestone.title + get :show, params: { id: milestone.safe_title, title: milestone.title } end it 'shows milestone page' do diff --git a/spec/controllers/dashboard/todos_controller_spec.rb b/spec/controllers/dashboard/todos_controller_spec.rb index e2c799f5205..d88beaff0e1 100644 --- a/spec/controllers/dashboard/todos_controller_spec.rb +++ b/spec/controllers/dashboard/todos_controller_spec.rb @@ -16,19 +16,19 @@ describe Dashboard::TodosController do it 'renders 404 when user does not have read access on given project' do unauthorized_project = create(:project, :private) - get :index, project_id: unauthorized_project.id + get :index, params: { project_id: unauthorized_project.id } expect(response).to have_gitlab_http_status(404) end it 'renders 404 when given project does not exists' do - get :index, project_id: 999 + get :index, params: { project_id: 999 } expect(response).to have_gitlab_http_status(404) end it 'renders 200 when filtering for "any project" todos' do - get :index, project_id: '' + get :index, params: { project_id: '' } expect(response).to have_gitlab_http_status(200) end @@ -36,7 +36,7 @@ describe Dashboard::TodosController do it 'renders 200 when user has access on given project' do authorized_project = create(:project, :public) - get :index, project_id: authorized_project.id + get :index, params: { project_id: authorized_project.id } expect(response).to have_gitlab_http_status(200) end @@ -46,7 +46,7 @@ describe Dashboard::TodosController do it 'renders 404 when user does not have read access on given group' do unauthorized_group = create(:group, :private) - get :index, group_id: unauthorized_group.id + get :index, params: { group_id: unauthorized_group.id } expect(response).to have_gitlab_http_status(404) end @@ -62,13 +62,13 @@ describe Dashboard::TodosController do end it 'redirects to last_page if page number is larger than number of pages' do - get :index, page: (last_page + 1).to_param + get :index, params: { page: (last_page + 1).to_param } expect(response).to redirect_to(dashboard_todos_path(page: last_page)) end it 'goes to the correct page' do - get :index, page: last_page + get :index, params: { page: last_page } expect(assigns(:todos).current_page).to eq(last_page) expect(response).to have_gitlab_http_status(200) @@ -76,7 +76,7 @@ describe Dashboard::TodosController do it 'does not redirect to external sites when provided a host field' do external_host = "www.example.com" - get :index, page: (last_page + 1).to_param, host: external_host + get :index, params: { page: (last_page + 1).to_param, host: external_host } expect(response).to redirect_to(dashboard_todos_path(page: last_page)) end @@ -87,7 +87,7 @@ describe Dashboard::TodosController do expect(user).to receive(:todos_pending_count).and_call_original - get :index, page: (last_page + 1).to_param, sort: :created_asc + get :index, params: { page: (last_page + 1).to_param, sort: :created_asc } expect(response).to redirect_to(dashboard_todos_path(page: last_page, sort: :created_asc)) end @@ -99,7 +99,7 @@ describe Dashboard::TodosController do expect(user).not_to receive(:todos_pending_count) - get :index, page: (last_page + 1).to_param, project_id: project.id + get :index, params: { page: (last_page + 1).to_param, project_id: project.id } expect(response).to redirect_to(dashboard_todos_path(page: last_page, project_id: project.id)) end @@ -111,7 +111,7 @@ describe Dashboard::TodosController do let(:todo) { create(:todo, :done, user: user, project: project, author: author) } it 'restores the todo to pending state' do - patch :restore, id: todo.id + patch :restore, params: { id: todo.id } expect(todo.reload).to be_pending expect(response).to have_gitlab_http_status(200) @@ -123,7 +123,7 @@ describe Dashboard::TodosController do let(:todos) { create_list(:todo, 2, :done, user: user, project: project, author: author) } it 'restores the todos to pending state' do - patch :bulk_restore, ids: todos.map(&:id) + patch :bulk_restore, params: { ids: todos.map(&:id) } todos.each do |todo| expect(todo.reload).to be_pending diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb index 2845f258f6f..d57367e931e 100644 --- a/spec/controllers/explore/projects_controller_spec.rb +++ b/spec/controllers/explore/projects_controller_spec.rb @@ -12,13 +12,13 @@ describe Explore::ProjectsController do end it 'sorts by last updated' do - get :trending, sort: 'updated_desc' + get :trending, params: { sort: 'updated_desc' } expect(assigns(:projects)).to eq [project2, project1] end it 'sorts by oldest updated' do - get :trending, sort: 'updated_asc' + get :trending, params: { sort: 'updated_asc' } expect(assigns(:projects)).to eq [project1, project2] end diff --git a/spec/controllers/google_api/authorizations_controller_spec.rb b/spec/controllers/google_api/authorizations_controller_spec.rb index 80d553f0f34..1e8e82da4f3 100644 --- a/spec/controllers/google_api/authorizations_controller_spec.rb +++ b/spec/controllers/google_api/authorizations_controller_spec.rb @@ -6,7 +6,7 @@ describe GoogleApi::AuthorizationsController do let(:token) { 'token' } let(:expires_at) { 1.hour.since.strftime('%s') } - subject { get :callback, code: 'xxx', state: @state } + subject { get :callback, params: { code: 'xxx', state: @state } } before do sign_in(user) diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb index 949ad532365..a0f40874db1 100644 --- a/spec/controllers/graphql_controller_spec.rb +++ b/spec/controllers/graphql_controller_spec.rb @@ -103,7 +103,7 @@ describe GraphqlController do } QUERY - post :execute, query: query, operationName: 'Echo', variables: variables, private_token: private_token + post :execute, params: { query: query, operationName: 'Echo', variables: variables, private_token: private_token } end def query_response diff --git a/spec/controllers/groups/avatars_controller_spec.rb b/spec/controllers/groups/avatars_controller_spec.rb index 7feecd0c380..772d1d0c1dd 100644 --- a/spec/controllers/groups/avatars_controller_spec.rb +++ b/spec/controllers/groups/avatars_controller_spec.rb @@ -10,7 +10,7 @@ describe Groups::AvatarsController do end it 'removes avatar from DB calling destroy' do - delete :destroy, group_id: group.path + delete :destroy, params: { group_id: group.path } @group = assigns(:group) expect(@group.avatar.present?).to be_falsey expect(@group).to be_valid diff --git a/spec/controllers/groups/boards_controller_spec.rb b/spec/controllers/groups/boards_controller_spec.rb index 99429c93b82..4228e727b52 100644 --- a/spec/controllers/groups/boards_controller_spec.rb +++ b/spec/controllers/groups/boards_controller_spec.rb @@ -105,7 +105,7 @@ describe Groups::BoardsController do end def list_boards(format: :html) - get :index, group_id: group, format: format + get :index, params: { group_id: group }, format: format end end @@ -183,8 +183,10 @@ describe Groups::BoardsController do end def read_board(board:, format: :html) - get :show, group_id: group, - id: board.to_param, + get :show, params: { + group_id: group, + id: board.to_param + }, format: format end end diff --git a/spec/controllers/groups/children_controller_spec.rb b/spec/controllers/groups/children_controller_spec.rb index 22d3076c269..4d5bb1488ab 100644 --- a/spec/controllers/groups/children_controller_spec.rb +++ b/spec/controllers/groups/children_controller_spec.rb @@ -16,7 +16,7 @@ describe Groups::ChildrenController do end it 'shows all children' do - get :index, group_id: group.to_param, format: :json + get :index, params: { group_id: group.to_param }, format: :json expect(assigns(:children)).to contain_exactly(public_project, private_project) end @@ -26,7 +26,7 @@ describe Groups::ChildrenController do group_member.destroy! private_project.add_guest(user) - get :index, group_id: group.to_param, format: :json + get :index, params: { group_id: group.to_param }, format: :json expect(assigns(:children)).to contain_exactly(public_project, private_project) end @@ -35,7 +35,7 @@ describe Groups::ChildrenController do context 'as a guest' do it 'shows the public children' do - get :index, group_id: group.to_param, format: :json + get :index, params: { group_id: group.to_param }, format: :json expect(assigns(:children)).to contain_exactly(public_project) end @@ -54,7 +54,7 @@ describe Groups::ChildrenController do end it 'shows all children' do - get :index, group_id: group.to_param, format: :json + get :index, params: { group_id: group.to_param }, format: :json expect(assigns(:children)).to contain_exactly(public_subgroup, private_subgroup, public_project, private_project) end @@ -65,7 +65,7 @@ describe Groups::ChildrenController do private_subgroup.add_guest(user) private_project.add_guest(user) - get :index, group_id: group.to_param, format: :json + get :index, params: { group_id: group.to_param }, format: :json expect(assigns(:children)).to contain_exactly(public_subgroup, private_subgroup, public_project, private_project) end @@ -74,7 +74,7 @@ describe Groups::ChildrenController do context 'as a guest' do it 'shows the public children' do - get :index, group_id: group.to_param, format: :json + get :index, params: { group_id: group.to_param }, format: :json expect(assigns(:children)).to contain_exactly(public_subgroup, public_project) end @@ -84,7 +84,7 @@ describe Groups::ChildrenController 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 + get :index, params: { group_id: group.to_param, filter: 'filter' }, format: :json group_json = json_response.first project_json = group_json['children'].first @@ -96,7 +96,7 @@ describe Groups::ChildrenController do 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 + get :index, params: { group_id: group.to_param, filter: 'filter' }, format: :json group_json = json_response.first matched_group_json = group_json['children'].first @@ -113,7 +113,7 @@ describe Groups::ChildrenController do 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 + get :index, params: { 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) @@ -136,7 +136,7 @@ describe Groups::ChildrenController do 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 + get :index, params: { group_id: subgroup.to_param, filter: 'test' }, format: :json expect(response).to have_http_status(200) end @@ -144,7 +144,7 @@ describe Groups::ChildrenController do 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 + get :index, params: { group_id: group.to_param, filter: 'match' }, format: :json expect(json_response).to be_kind_of(Array) expect(json_response.size).to eq(1) @@ -155,7 +155,7 @@ describe Groups::ChildrenController do 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 + get :index, params: { group_id: subgroup.to_param, filter: 'test' }, format: :json expect(json_response).to eq([]) end @@ -179,7 +179,7 @@ describe Groups::ChildrenController do end group_to_nest.update!(parent: subgroup) - get :index, group_id: group.to_param, filter: 'filter', per_page: 3, format: :json + get :index, params: { group_id: group.to_param, filter: 'filter', per_page: 3 }, format: :json expect(response).to have_gitlab_http_status(200) end @@ -187,7 +187,7 @@ describe Groups::ChildrenController do 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 + get :index, params: { group_id: group.to_param, filter: 'filter', per_page: 1 }, format: :json expect(response).to include_pagination_headers end @@ -203,7 +203,7 @@ describe Groups::ChildrenController do let(:expected_queries_per_project) { 0 } def get_list - get :index, group_id: group.to_param, format: :json + get :index, params: { group_id: group.to_param }, format: :json end it 'queries the expected amount for a group row' do @@ -227,7 +227,7 @@ describe Groups::ChildrenController do let(:extra_queries_for_hierarchies) { 1 } def get_filtered_list - get :index, group_id: group.to_param, filter: 'filter', format: :json + get :index, params: { group_id: group.to_param, filter: 'filter' }, format: :json end it 'queries the expected amount when nested rows are increased for a group' do @@ -276,13 +276,13 @@ describe Groups::ChildrenController do 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 + get :index, params: { 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 + get :index, params: { group_id: group.to_param, sort: 'id_desc', page: 2 }, format: :json expect(assigns(:children)).to contain_exactly(other_project) end @@ -294,13 +294,13 @@ describe Groups::ChildrenController do 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 + get :index, params: { 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 + get :index, params: { 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 @@ -310,7 +310,7 @@ describe Groups::ChildrenController do let!(:first_page_projects) { create_list(:project, per_page, :public, namespace: group) } it 'correctly calculates the counts' do - get :index, group_id: group.to_param, sort: 'id_asc', page: 2, format: :json + get :index, params: { group_id: group.to_param, sort: 'id_asc', page: 2 }, format: :json expect(response).to have_gitlab_http_status(200) end diff --git a/spec/controllers/groups/clusters/applications_controller_spec.rb b/spec/controllers/groups/clusters/applications_controller_spec.rb index 68a798542b6..dd5263b077c 100644 --- a/spec/controllers/groups/clusters/applications_controller_spec.rb +++ b/spec/controllers/groups/clusters/applications_controller_spec.rb @@ -81,7 +81,7 @@ describe Groups::Clusters::ApplicationsController do end def go - post :create, params.merge(group_id: group) + post :create, params: params.merge(group_id: group) end end end diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb index 6e130f830a2..0f28499194e 100644 --- a/spec/controllers/groups/clusters_controller_spec.rb +++ b/spec/controllers/groups/clusters_controller_spec.rb @@ -17,7 +17,7 @@ describe Groups::ClustersController do describe 'GET index' do def go(params = {}) - get :index, params.reverse_merge(group_id: group) + get :index, params: params.reverse_merge(group_id: group) end context 'when feature flag is not enabled' do @@ -104,7 +104,7 @@ describe Groups::ClustersController do describe 'GET new' do def go - get :new, group_id: group + get :new, params: { group_id: group } end describe 'functionality for new cluster' do @@ -198,7 +198,7 @@ describe Groups::ClustersController do end def go - post :create_gcp, params.merge(group_id: group) + post :create_gcp, params: params.merge(group_id: group) end describe 'functionality' do @@ -287,7 +287,7 @@ describe Groups::ClustersController do end def go - post :create_user, params.merge(group_id: group) + post :create_user, params: params.merge(group_id: group) end describe 'functionality' do @@ -353,8 +353,10 @@ describe Groups::ClustersController do def go get :cluster_status, - group_id: group.to_param, - id: cluster, + params: { + group_id: group.to_param, + id: cluster + }, format: :json end @@ -390,8 +392,10 @@ describe Groups::ClustersController do def go get :show, - group_id: group, - id: cluster + params: { + group_id: group, + id: cluster + } end describe 'functionality' do @@ -417,7 +421,7 @@ describe Groups::ClustersController do describe 'PUT update' do def go(format: :html) - put :update, params.merge( + put :update, params: params.merge( group_id: group.to_param, id: cluster, format: format @@ -505,8 +509,10 @@ describe Groups::ClustersController do def go delete :destroy, - group_id: group, - id: cluster + params: { + group_id: group, + id: cluster + } end describe 'functionality' do diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb index 362d5cc4514..ed38dadfd6b 100644 --- a/spec/controllers/groups/group_members_controller_spec.rb +++ b/spec/controllers/groups/group_members_controller_spec.rb @@ -6,7 +6,7 @@ describe Groups::GroupMembersController do describe 'GET index' do it 'renders index with 200 status code' do - get :index, group_id: group + get :index, params: { group_id: group } expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:index) @@ -26,9 +26,11 @@ describe Groups::GroupMembersController do end it 'returns 403' do - post :create, group_id: group, - user_ids: group_user.id, - access_level: Gitlab::Access::GUEST + post :create, params: { + group_id: group, + user_ids: group_user.id, + access_level: Gitlab::Access::GUEST + } expect(response).to have_gitlab_http_status(403) expect(group.users).not_to include group_user @@ -41,9 +43,11 @@ describe Groups::GroupMembersController do end it 'adds user to members' do - post :create, group_id: group, - user_ids: group_user.id, - access_level: Gitlab::Access::GUEST + post :create, params: { + group_id: group, + user_ids: group_user.id, + access_level: Gitlab::Access::GUEST + } expect(response).to set_flash.to 'Users were successfully added.' expect(response).to redirect_to(group_group_members_path(group)) @@ -51,9 +55,11 @@ describe Groups::GroupMembersController do end it 'adds no user to members' do - post :create, group_id: group, - user_ids: '', - access_level: Gitlab::Access::GUEST + post :create, params: { + group_id: group, + user_ids: '', + access_level: Gitlab::Access::GUEST + } expect(response).to set_flash.to 'No users specified.' expect(response).to redirect_to(group_group_members_path(group)) @@ -72,9 +78,11 @@ describe Groups::GroupMembersController do Gitlab::Access.options.each do |label, value| it "can change the access level to #{label}" do - xhr :put, :update, group_member: { access_level: value }, - group_id: group, - id: requester + put :update, params: { + group_member: { access_level: value }, + group_id: group, + id: requester + }, xhr: true expect(requester.reload.human_access).to eq(label) end @@ -90,7 +98,7 @@ describe Groups::GroupMembersController do context 'when member is not found' do it 'returns 403' do - delete :destroy, group_id: group, id: 42 + delete :destroy, params: { group_id: group, id: 42 } expect(response).to have_gitlab_http_status(403) end @@ -103,7 +111,7 @@ describe Groups::GroupMembersController do end it 'returns 403' do - delete :destroy, group_id: group, id: member + delete :destroy, params: { group_id: group, id: member } expect(response).to have_gitlab_http_status(403) expect(group.members).to include member @@ -116,7 +124,7 @@ describe Groups::GroupMembersController do end it '[HTML] removes user from members' do - delete :destroy, group_id: group, id: member + delete :destroy, params: { group_id: group, id: member } expect(response).to set_flash.to 'User was successfully removed from group.' expect(response).to redirect_to(group_group_members_path(group)) @@ -124,7 +132,7 @@ describe Groups::GroupMembersController do end it '[JS] removes user from members' do - xhr :delete, :destroy, group_id: group, id: member + delete :destroy, params: { group_id: group, id: member }, xhr: true expect(response).to be_success expect(group.members).not_to include member @@ -140,7 +148,7 @@ describe Groups::GroupMembersController do context 'when member is not found' do it 'returns 404' do - delete :leave, group_id: group + delete :leave, params: { group_id: group } expect(response).to have_gitlab_http_status(404) end @@ -153,7 +161,7 @@ describe Groups::GroupMembersController do end it 'removes user from members' do - delete :leave, group_id: group + delete :leave, params: { group_id: group } expect(response).to set_flash.to "You left the \"#{group.name}\" group." expect(response).to redirect_to(dashboard_groups_path) @@ -161,7 +169,7 @@ describe Groups::GroupMembersController do end it 'supports json request' do - delete :leave, group_id: group, format: :json + delete :leave, params: { group_id: group }, format: :json expect(response).to have_gitlab_http_status(200) expect(json_response['notice']).to eq "You left the \"#{group.name}\" group." @@ -174,7 +182,7 @@ describe Groups::GroupMembersController do end it 'cannot removes himself from the group' do - delete :leave, group_id: group + delete :leave, params: { group_id: group } expect(response).to have_gitlab_http_status(403) end @@ -186,7 +194,7 @@ describe Groups::GroupMembersController do end it 'removes user from members' do - delete :leave, group_id: group + delete :leave, params: { group_id: group } expect(response).to set_flash.to 'Your access request to the group has been withdrawn.' expect(response).to redirect_to(group_path(group)) @@ -203,7 +211,7 @@ describe Groups::GroupMembersController do end it 'creates a new GroupMember that is not a team member' do - post :request_access, group_id: group + post :request_access, params: { group_id: group } expect(response).to set_flash.to 'Your request for access has been queued for review.' expect(response).to redirect_to(group_path(group)) @@ -221,7 +229,7 @@ describe Groups::GroupMembersController do context 'when member is not found' do it 'returns 403' do - post :approve_access_request, group_id: group, id: 42 + post :approve_access_request, params: { group_id: group, id: 42 } expect(response).to have_gitlab_http_status(403) end @@ -234,7 +242,7 @@ describe Groups::GroupMembersController do end it 'returns 403' do - post :approve_access_request, group_id: group, id: member + post :approve_access_request, params: { group_id: group, id: member } expect(response).to have_gitlab_http_status(403) expect(group.members).not_to include member @@ -247,7 +255,7 @@ describe Groups::GroupMembersController do end it 'adds user to members' do - post :approve_access_request, group_id: group, id: member + post :approve_access_request, params: { group_id: group, id: member } expect(response).to redirect_to(group_group_members_path(group)) expect(group.members).to include member diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb index 185b6b4ce57..fa664a29066 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 set(:group_label_1) { create(:group_label, group: group, title: 'group_label_1') } it 'returns group and project labels by default' do - get :index, group_id: group, format: :json + get :index, params: { group_id: group }, format: :json label_ids = json_response.map {|label| label['title']} expect(label_ids).to match_array([label_1.title, group_label_1.title]) @@ -31,7 +31,7 @@ describe Groups::LabelsController do end it 'returns ancestor group labels', :nested_groups do - get :index, group_id: subgroup, include_ancestor_groups: true, only_group_labels: true, format: :json + get :index, params: { group_id: subgroup, include_ancestor_groups: true, only_group_labels: true }, format: :json label_ids = json_response.map {|label| label['title']} expect(label_ids).to match_array([group_label_1.title, subgroup_label_1.title]) @@ -43,7 +43,7 @@ describe Groups::LabelsController do it 'allows user to toggle subscription on group labels' do label = create(:group_label, group: group) - post :toggle_subscription, group_id: group.to_param, id: label.to_param + post :toggle_subscription, params: { group_id: group.to_param, id: label.to_param } expect(response).to have_gitlab_http_status(200) end diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb index 42723bb3820..b8e1e08cff7 100644 --- a/spec/controllers/groups/milestones_controller_spec.rb +++ b/spec/controllers/groups/milestones_controller_spec.rb @@ -33,7 +33,7 @@ describe Groups::MilestonesController do describe '#index' do it 'shows group milestones page' do - get :index, group_id: group.to_param + get :index, params: { group_id: group.to_param } expect(response).to have_gitlab_http_status(200) end @@ -44,7 +44,7 @@ describe Groups::MilestonesController do let!(:legacy_milestone2) { create(:milestone, project: project2, title: 'legacy') } it 'lists legacy group milestones and group milestones' do - get :index, group_id: group.to_param, format: :json + get :index, params: { group_id: group.to_param }, format: :json milestones = JSON.parse(response.body) @@ -67,7 +67,7 @@ describe Groups::MilestonesController do expect(GlobalMilestone).to receive(:build) expect(Milestone).not_to receive(:find_by_iid) - get :show, group_id: group.to_param, id: title, title: milestone1.safe_title + get :show, params: { group_id: group.to_param, id: title, title: milestone1.safe_title } end end @@ -76,7 +76,7 @@ describe Groups::MilestonesController do expect(GlobalMilestone).not_to receive(:build) expect(Milestone).to receive(:find_by_iid) - get :show, group_id: group.to_param, id: group_milestone.id + get :show, params: { group_id: group.to_param, id: group_milestone.id } end end end @@ -86,8 +86,10 @@ describe Groups::MilestonesController do describe "#create" do it "creates group milestone with Chinese title" do post :create, - group_id: group.to_param, - milestone: milestone_params + params: { + group_id: group.to_param, + milestone: milestone_params + } milestone = Milestone.find_by_title(title) @@ -105,9 +107,11 @@ describe Groups::MilestonesController do milestone_params[:title] = "title changed" put :update, - id: milestone.iid, - group_id: group.to_param, - milestone: milestone_params + params: { + id: milestone.iid, + group_id: group.to_param, + milestone: milestone_params + } milestone.reload expect(response).to redirect_to(group_milestone_path(group, milestone.iid)) @@ -124,10 +128,12 @@ describe Groups::MilestonesController do milestone_params[:state_event] = "close" put :update, - id: milestone1.title.to_slug.to_s, - group_id: group.to_param, - milestone: milestone_params, - title: milestone1.title + params: { + id: milestone1.title.to_slug.to_s, + group_id: group.to_param, + milestone: milestone_params, + title: milestone1.title + } expect(response).to redirect_to(group_milestone_path(group, milestone1.safe_title, title: milestone1.title)) @@ -145,7 +151,7 @@ describe Groups::MilestonesController do let(:milestone) { create(:milestone, group: group) } it "removes milestone" do - delete :destroy, group_id: group.to_param, id: milestone.iid, format: :js + delete :destroy, params: { group_id: group.to_param, id: milestone.iid }, format: :js expect(response).to be_success expect { Milestone.find(milestone.id) }.to raise_exception(ActiveRecord::RecordNotFound) @@ -162,7 +168,7 @@ describe Groups::MilestonesController do context 'non-show path' do context 'with exactly matching casing' do it 'does not redirect' do - get :index, group_id: group.to_param + get :index, params: { group_id: group.to_param } expect(response).not_to have_gitlab_http_status(301) end @@ -170,7 +176,7 @@ describe Groups::MilestonesController do context 'with different casing' do it 'redirects to the correct casing' do - get :index, group_id: group.to_param.upcase + get :index, params: { group_id: group.to_param.upcase } expect(response).to redirect_to(group_milestones_path(group.to_param)) expect(controller).not_to set_flash[:notice] @@ -181,7 +187,7 @@ describe Groups::MilestonesController do context 'show path' do context 'with exactly matching casing' do it 'does not redirect' do - get :show, group_id: group.to_param, id: title + get :show, params: { group_id: group.to_param, id: title } expect(response).not_to have_gitlab_http_status(301) end @@ -189,7 +195,7 @@ describe Groups::MilestonesController do context 'with different casing' do it 'redirects to the correct casing' do - get :show, group_id: group.to_param.upcase, id: title + get :show, params: { group_id: group.to_param.upcase, id: title } expect(response).to redirect_to(group_milestone_path(group.to_param, title)) expect(controller).not_to set_flash[:notice] @@ -202,7 +208,7 @@ describe Groups::MilestonesController do let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } it 'redirects to the canonical path' do - get :merge_requests, group_id: redirect_route.path, id: title + get :merge_requests, params: { group_id: redirect_route.path, id: title } expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title)) expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) @@ -212,7 +218,7 @@ describe Groups::MilestonesController do let(:redirect_route) { group.redirect_routes.create(path: 'http') } it 'does not modify the requested host' do - get :merge_requests, group_id: redirect_route.path, id: title + get :merge_requests, params: { group_id: redirect_route.path, id: title } expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title)) expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) @@ -224,7 +230,7 @@ describe Groups::MilestonesController do let(:redirect_route) { group.redirect_routes.create(path: 'oups') } it 'does not modify the /groups part of the path' do - get :merge_requests, group_id: redirect_route.path, id: title + get :merge_requests, params: { group_id: redirect_route.path, id: title } expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title)) expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) @@ -236,7 +242,7 @@ describe Groups::MilestonesController do let(:redirect_route) { group.redirect_routes.create(path: 'oups/oup') } it 'does not modify the /groups part of the path' do - get :merge_requests, group_id: redirect_route.path, id: title + get :merge_requests, params: { group_id: redirect_route.path, id: title } expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title)) expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) @@ -250,16 +256,20 @@ describe Groups::MilestonesController do context 'when requesting the canonical path with different casing' do it 'does not 404' do post :create, - group_id: group.to_param, - milestone: { title: title } + params: { + group_id: group.to_param, + milestone: { title: title } + } expect(response).not_to have_gitlab_http_status(404) end it 'does not redirect to the correct casing' do post :create, - group_id: group.to_param, - milestone: { title: title } + params: { + group_id: group.to_param, + milestone: { title: title } + } expect(response).not_to have_gitlab_http_status(301) end @@ -270,8 +280,10 @@ describe Groups::MilestonesController do it 'returns not found' do post :create, - group_id: redirect_route.path, - milestone: { title: title } + params: { + group_id: redirect_route.path, + milestone: { title: title } + } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb index 598fb84552f..469459bfc02 100644 --- a/spec/controllers/groups/runners_controller_spec.rb +++ b/spec/controllers/groups/runners_controller_spec.rb @@ -22,7 +22,7 @@ describe Groups::RunnersController do new_desc = runner.description.swapcase expect do - post :update, params.merge(runner: { description: new_desc } ) + post :update, params: params.merge(runner: { description: new_desc } ) end.to change { runner.ensure_runner_queue_value } runner.reload @@ -34,7 +34,7 @@ describe Groups::RunnersController do describe '#destroy' do it 'destroys the runner' do - delete :destroy, params + delete :destroy, params: params expect(response).to have_gitlab_http_status(302) expect(Ci::Runner.find_by(id: runner.id)).to be_nil @@ -46,7 +46,7 @@ describe Groups::RunnersController do runner.update(active: false) expect do - post :resume, params + post :resume, params: params end.to change { runner.ensure_runner_queue_value } runner.reload @@ -61,7 +61,7 @@ describe Groups::RunnersController do runner.update(active: true) expect do - post :pause, params + post :pause, params: params end.to change { runner.ensure_runner_queue_value } runner.reload diff --git a/spec/controllers/groups/settings/ci_cd_controller_spec.rb b/spec/controllers/groups/settings/ci_cd_controller_spec.rb index 06ccace8242..40673d10b91 100644 --- a/spec/controllers/groups/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/groups/settings/ci_cd_controller_spec.rb @@ -5,30 +5,65 @@ describe Groups::Settings::CiCdController do let(:user) { create(:user) } before do - group.add_maintainer(user) sign_in(user) end describe 'GET #show' do - it 'renders show with 200 status code' do - get :show, group_id: group + context 'when user is owner' do + before do + group.add_owner(user) + end - expect(response).to have_gitlab_http_status(200) - expect(response).to render_template(:show) + it 'renders show with 200 status code' do + get :show, params: { group_id: group } + + expect(response).to have_gitlab_http_status(200) + expect(response).to render_template(:show) + end + end + + context 'when user is not owner' do + before do + group.add_maintainer(user) + end + + it 'renders a 404' do + get :show, params: { group_id: group } + + expect(response).to have_gitlab_http_status(404) + end end end describe 'PUT #reset_registration_token' do - subject { put :reset_registration_token, group_id: group } + subject { put :reset_registration_token, params: { group_id: group } } - it 'resets runner registration token' do - expect { subject }.to change { group.reload.runners_token } + context 'when user is owner' do + before do + group.add_owner(user) + end + + it 'resets runner registration token' do + expect { subject }.to change { group.reload.runners_token } + end + + it 'redirects the user to admin runners page' do + subject + + expect(response).to redirect_to(group_settings_ci_cd_path) + end end - it 'redirects the user to admin runners page' do - subject + context 'when user is not owner' do + before do + group.add_maintainer(user) + end + + it 'renders a 404' do + subject - expect(response).to redirect_to(group_settings_ci_cd_path) + expect(response).to have_gitlab_http_status(404) + end end end end diff --git a/spec/controllers/groups/shared_projects_controller_spec.rb b/spec/controllers/groups/shared_projects_controller_spec.rb index 003c8c262e7..dab7700cf64 100644 --- a/spec/controllers/groups/shared_projects_controller_spec.rb +++ b/spec/controllers/groups/shared_projects_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Groups::SharedProjectsController do def get_shared_projects(params = {}) - get :index, params.reverse_merge(format: :json, group_id: group.full_path) + get :index, params: params.reverse_merge(format: :json, group_id: group.full_path) end def share_project(project) diff --git a/spec/controllers/groups/uploads_controller_spec.rb b/spec/controllers/groups/uploads_controller_spec.rb index 5a7281ed704..0104ba827da 100644 --- a/spec/controllers/groups/uploads_controller_spec.rb +++ b/spec/controllers/groups/uploads_controller_spec.rb @@ -15,6 +15,6 @@ describe Groups::UploadsController do def post_authorize(verified: true) request.headers.merge!(workhorse_internal_api_request_header) if verified - post :authorize, group_id: model.full_path, format: :json + post :authorize, params: { group_id: model.full_path }, format: :json end end diff --git a/spec/controllers/groups/variables_controller_spec.rb b/spec/controllers/groups/variables_controller_spec.rb index e5ac5634f95..29ec3588316 100644 --- a/spec/controllers/groups/variables_controller_spec.rb +++ b/spec/controllers/groups/variables_controller_spec.rb @@ -13,7 +13,7 @@ describe Groups::VariablesController do let!(:variable) { create(:ci_group_variable, group: group) } subject do - get :show, group_id: group, format: :json + get :show, params: { group_id: group }, format: :json end include_examples 'GET #show lists all variables' @@ -25,8 +25,10 @@ describe Groups::VariablesController do subject do patch :update, - group_id: group, - variables_attributes: variables_attributes, + params: { + group_id: group, + variables_attributes: variables_attributes + }, format: :json end diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index 4b0dc4c9b69..7d87b33e503 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -15,7 +15,7 @@ describe GroupsController do it 'renders the new page' do sign_in(member) - get :new, parent_id: group.id + get :new, params: { parent_id: group.id } expect(response).to render_template(:new) end @@ -25,7 +25,7 @@ describe GroupsController do it 'renders the 404 page' do sign_in(member) - get :new, parent_id: group.id + get :new, params: { parent_id: group.id } expect(response).not_to render_template(:new) expect(response.status).to eq(404) @@ -42,7 +42,7 @@ describe GroupsController do it 'assigns events for all the projects in the group' do create(:event, project: project) - get :show, id: group.to_param, format: :atom + get :show, params: { id: group.to_param }, format: :atom expect(assigns(:events)).not_to be_empty end @@ -53,7 +53,7 @@ describe GroupsController do it 'sets the badge API endpoint' do sign_in(owner) - get :edit, id: group.to_param + get :edit, params: { id: group.to_param } expect(assigns(:badge_api_endpoint)).not_to be_nil end @@ -102,7 +102,7 @@ describe GroupsController do create(:event, project: project) end - get :activity, id: group.to_param, format: :json + get :activity, params: { id: group.to_param }, format: :json expect(response).to have_gitlab_http_status(200) expect(json_response['count']).to eq(3) @@ -120,7 +120,7 @@ describe GroupsController do owner.update_attribute(:can_create_group, can_create_group_status) sign_in(owner) - post :create, group: { parent_id: group.id, path: 'subgroup' } + post :create, params: { group: { parent_id: group.id, path: 'subgroup' } } expect(response).to be_redirect expect(response.body).to match(%r{http://test.host/#{group.path}/subgroup}) @@ -134,7 +134,7 @@ describe GroupsController do previous_group_count = Group.count - post :create, group: { parent_id: group.id, path: 'subgroup' } + post :create, params: { group: { parent_id: group.id, path: 'subgroup' } } expect(response).to render_template(:new) expect(Group.count).to eq(previous_group_count) @@ -157,7 +157,7 @@ describe GroupsController do it 'creates the Group' do original_group_count = Group.count - post :create, group: { path: 'subgroup' } + post :create, params: { group: { path: 'subgroup' } } expect(Group.count).to eq(original_group_count + 1) expect(response).to be_redirect @@ -172,7 +172,7 @@ describe GroupsController do it 'does not create the Group' do original_group_count = Group.count - post :create, group: { path: 'subgroup' } + post :create, params: { group: { path: 'subgroup' } } expect(Group.count).to eq(original_group_count) expect(response).to render_template(:new) @@ -215,12 +215,12 @@ describe GroupsController do context 'sorting by votes' do it 'sorts most popular issues' do - get :issues, id: group.to_param, sort: 'upvotes_desc' + get :issues, params: { id: group.to_param, sort: 'upvotes_desc' } expect(assigns(:issues)).to eq [issue_2, issue_1] end it 'sorts least popular issues' do - get :issues, id: group.to_param, sort: 'downvotes_desc' + get :issues, params: { id: group.to_param, sort: 'downvotes_desc' } expect(assigns(:issues)).to eq [issue_2, issue_1] end end @@ -233,19 +233,19 @@ describe GroupsController do end it 'works with popularity sort' do - get :issues, id: group.to_param, search: 'foo', sort: 'popularity' + get :issues, params: { id: group.to_param, search: 'foo', sort: 'popularity' } expect(assigns(:issues)).to eq([issue_1]) end it 'works with priority sort' do - get :issues, id: group.to_param, search: 'foo', sort: 'priority' + get :issues, params: { id: group.to_param, search: 'foo', sort: 'priority' } expect(assigns(:issues)).to eq([issue_1]) end it 'works with label priority sort' do - get :issues, id: group.to_param, search: 'foo', sort: 'label_priority' + get :issues, params: { id: group.to_param, search: 'foo', sort: 'label_priority' } expect(assigns(:issues)).to eq([issue_1]) end @@ -266,12 +266,12 @@ describe GroupsController do context 'sorting by votes' do it 'sorts most popular merge requests' do - get :merge_requests, id: group.to_param, sort: 'upvotes_desc' + get :merge_requests, params: { id: group.to_param, sort: 'upvotes_desc' } expect(assigns(:merge_requests)).to eq [merge_request_2, merge_request_1] end it 'sorts least popular merge requests' do - get :merge_requests, id: group.to_param, sort: 'downvotes_desc' + get :merge_requests, params: { id: group.to_param, sort: 'downvotes_desc' } expect(assigns(:merge_requests)).to eq [merge_request_2, merge_request_1] end end @@ -282,7 +282,7 @@ describe GroupsController do it 'returns 404' do sign_in(create(:user)) - delete :destroy, id: group.to_param + delete :destroy, params: { id: group.to_param } expect(response.status).to eq(404) end @@ -295,12 +295,12 @@ describe GroupsController do it 'schedules a group destroy' do Sidekiq::Testing.fake! do - expect { delete :destroy, id: group.to_param }.to change(GroupDestroyWorker.jobs, :size).by(1) + expect { delete :destroy, params: { id: group.to_param } }.to change(GroupDestroyWorker.jobs, :size).by(1) end end it 'redirects to the root path' do - delete :destroy, id: group.to_param + delete :destroy, params: { id: group.to_param } expect(response).to redirect_to(root_path) end @@ -313,7 +313,7 @@ describe GroupsController do end it 'updates the path successfully' do - post :update, id: group.to_param, group: { path: 'new_path' } + post :update, params: { id: group.to_param, group: { path: 'new_path' } } expect(response).to have_gitlab_http_status(302) expect(controller).to set_flash[:notice] @@ -321,7 +321,7 @@ describe GroupsController do it 'does not update the path on error' do allow_any_instance_of(Group).to receive(:move_dir).and_raise(Gitlab::UpdatePathError) - post :update, id: group.to_param, group: { path: 'new_path' } + post :update, params: { id: group.to_param, group: { path: 'new_path' } } expect(assigns(:group).errors).not_to be_empty expect(assigns(:group).path).not_to eq('new_path') @@ -337,7 +337,7 @@ describe GroupsController do context 'when requesting groups at the root path' do before do allow(request).to receive(:original_fullpath).and_return("/#{group_full_path}") - get :show, id: group_full_path + get :show, params: { id: group_full_path } end context 'when requesting the canonical path with different casing' do @@ -384,7 +384,7 @@ describe GroupsController do context 'non-show path' do context 'with exactly matching casing' do it 'does not redirect' do - get :issues, id: group.to_param + get :issues, params: { id: group.to_param } expect(response).not_to have_gitlab_http_status(301) end @@ -392,7 +392,7 @@ describe GroupsController do context 'with different casing' do it 'redirects to the correct casing' do - get :issues, id: group.to_param.upcase + get :issues, params: { id: group.to_param.upcase } expect(response).to redirect_to(issues_group_path(group.to_param)) expect(controller).not_to set_flash[:notice] @@ -403,7 +403,7 @@ describe GroupsController do context 'show path' do context 'with exactly matching casing' do it 'does not redirect' do - get :show, id: group.to_param + get :show, params: { id: group.to_param } expect(response).not_to have_gitlab_http_status(301) end @@ -411,7 +411,7 @@ describe GroupsController do context 'with different casing' do it 'redirects to the correct casing at the root path' do - get :show, id: group.to_param.upcase + get :show, params: { id: group.to_param.upcase } expect(response).to redirect_to(group) expect(controller).not_to set_flash[:notice] @@ -424,7 +424,7 @@ describe GroupsController do let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } it 'redirects to the canonical path' do - get :issues, id: redirect_route.path + get :issues, params: { id: redirect_route.path } expect(response).to redirect_to(issues_group_path(group.to_param)) expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) @@ -434,7 +434,7 @@ describe GroupsController do let(:redirect_route) { group.redirect_routes.create(path: 'http') } it 'does not modify the requested host' do - get :issues, id: redirect_route.path + get :issues, params: { id: redirect_route.path } expect(response).to redirect_to(issues_group_path(group.to_param)) expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) @@ -446,7 +446,7 @@ describe GroupsController do let(:redirect_route) { group.redirect_routes.create(path: 'oups') } it 'does not modify the /groups part of the path' do - get :issues, id: redirect_route.path + get :issues, params: { id: redirect_route.path } expect(response).to redirect_to(issues_group_path(group.to_param)) expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) @@ -458,7 +458,7 @@ describe GroupsController do let(:redirect_route) { group.redirect_routes.create(path: 'oups/oup') } it 'does not modify the /groups part of the path' do - get :issues, id: redirect_route.path + get :issues, params: { id: redirect_route.path } expect(response).to redirect_to(issues_group_path(group.to_param)) expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) @@ -470,13 +470,13 @@ describe GroupsController do context 'for a POST request' do context 'when requesting the canonical path with different casing' do it 'does not 404' do - post :update, id: group.to_param.upcase, group: { path: 'new_path' } + post :update, params: { id: group.to_param.upcase, group: { path: 'new_path' } } expect(response).not_to have_gitlab_http_status(404) end it 'does not redirect to the correct casing' do - post :update, id: group.to_param.upcase, group: { path: 'new_path' } + post :update, params: { id: group.to_param.upcase, group: { path: 'new_path' } } expect(response).not_to have_gitlab_http_status(301) end @@ -486,7 +486,7 @@ describe GroupsController do let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } it 'returns not found' do - post :update, id: redirect_route.path, group: { path: 'new_path' } + post :update, params: { id: redirect_route.path, group: { path: 'new_path' } } expect(response).to have_gitlab_http_status(404) end @@ -496,13 +496,13 @@ describe GroupsController do context 'for a DELETE request' do context 'when requesting the canonical path with different casing' do it 'does not 404' do - delete :destroy, id: group.to_param.upcase + delete :destroy, params: { id: group.to_param.upcase } expect(response).not_to have_gitlab_http_status(404) end it 'does not redirect to the correct casing' do - delete :destroy, id: group.to_param.upcase + delete :destroy, params: { id: group.to_param.upcase } expect(response).not_to have_gitlab_http_status(301) end @@ -512,7 +512,7 @@ describe GroupsController do let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } it 'returns not found' do - delete :destroy, id: redirect_route.path + delete :destroy, params: { id: redirect_route.path } expect(response).to have_gitlab_http_status(404) end @@ -537,8 +537,10 @@ describe GroupsController do before do put :transfer, - id: group.to_param, - new_parent_group_id: new_parent_group.id + params: { + id: group.to_param, + new_parent_group_id: new_parent_group.id + } end it 'should return a notice' do @@ -556,8 +558,10 @@ describe GroupsController do before do put :transfer, - id: group.to_param, - new_parent_group_id: '' + params: { + id: group.to_param, + new_parent_group_id: '' + } end it 'should return a notice' do @@ -578,8 +582,10 @@ describe GroupsController do allow_any_instance_of(::Groups::TransferService).to receive(:proceed_to_transfer).and_raise(Gitlab::UpdatePathError, 'namespace directory cannot be moved') put :transfer, - id: group.to_param, - new_parent_group_id: new_parent_group.id + params: { + id: group.to_param, + new_parent_group_id: new_parent_group.id + } end it 'should return an alert' do @@ -598,8 +604,10 @@ describe GroupsController do before do put :transfer, - id: group.to_param, - new_parent_group_id: new_parent_group.id + params: { + id: group.to_param, + new_parent_group_id: new_parent_group.id + } end it 'should be denied' do diff --git a/spec/controllers/health_check_controller_spec.rb b/spec/controllers/health_check_controller_spec.rb index 387ca46ef6f..29e159ad5d7 100644 --- a/spec/controllers/health_check_controller_spec.rb +++ b/spec/controllers/health_check_controller_spec.rb @@ -37,7 +37,7 @@ describe HealthCheckController do end it 'supports passing the token in query params' do - get :index, token: token + get :index, params: { token: token } expect(response).to be_success expect(response.content_type).to eq 'text/plain' @@ -74,7 +74,7 @@ describe HealthCheckController do end it 'supports successful responses for specific checks' do - get :index, checks: 'email', format: :json + get :index, params: { checks: 'email' }, format: :json expect(response).to be_success expect(response.content_type).to eq 'application/json' @@ -124,7 +124,7 @@ describe HealthCheckController do end it 'supports failure responses for specific checks' do - get :index, checks: 'email', format: :json + get :index, params: { checks: 'email' }, format: :json expect(response).to have_gitlab_http_status(500) expect(response.content_type).to eq 'application/json' diff --git a/spec/controllers/health_controller_spec.rb b/spec/controllers/health_controller_spec.rb index ec73c89cb11..f685f2b41c0 100644 --- a/spec/controllers/health_controller_spec.rb +++ b/spec/controllers/health_controller_spec.rb @@ -18,7 +18,7 @@ describe HealthController do shared_context 'endpoint responding with readiness data' do let(:request_params) { {} } - subject { get :readiness, request_params } + subject { get :readiness, params: request_params } it 'responds with readiness checks data' do subject @@ -112,7 +112,7 @@ describe HealthController do context 'token passed as URL param' do it_behaves_like 'endpoint responding with liveness data' do - subject { get :liveness, token: token } + subject { get :liveness, params: { token: token } } end end end diff --git a/spec/controllers/help_controller_spec.rb b/spec/controllers/help_controller_spec.rb index 21d59c62613..5cb284e7e2d 100644 --- a/spec/controllers/help_controller_spec.rb +++ b/spec/controllers/help_controller_spec.rb @@ -43,7 +43,7 @@ describe HelpController do context 'for Markdown formats' do context 'when requested file exists' do before do - get :show, path: 'ssh/README', format: :md + get :show, params: { path: 'ssh/README' }, format: :md end it 'assigns to @markdown' do @@ -58,7 +58,7 @@ describe HelpController do context 'when requested file is missing' do it 'renders not found' do - get :show, path: 'foo/bar', format: :md + get :show, params: { path: 'foo/bar' }, format: :md expect(response).to be_not_found end end @@ -68,7 +68,9 @@ describe HelpController do context 'when requested file exists' do it 'renders the raw file' do get :show, - path: 'user/project/img/labels_default', + params: { + path: 'user/project/img/labels_default' + }, format: :png expect(response).to be_success expect(response.content_type).to eq 'image/png' @@ -79,7 +81,9 @@ describe HelpController do context 'when requested file is missing' do it 'renders not found' do get :show, - path: 'foo/bar', + params: { + path: 'foo/bar' + }, format: :png expect(response).to be_not_found end @@ -89,7 +93,9 @@ describe HelpController do context 'for other formats' do it 'always renders not found' do get :show, - path: 'ssh/README', + params: { + path: 'ssh/README' + }, format: :foo expect(response).to be_not_found end diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index be49b92d23f..51793f2c048 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -237,7 +237,7 @@ describe Import::BitbucketController do .to receive(:new).with(bitbucket_repo, test_name, nested_namespace, user, access_params) .and_return(double(execute: project)) - post :create, { target_namespace: nested_namespace.full_path, new_name: test_name, format: :json } + post :create, params: { target_namespace: nested_namespace.full_path, new_name: test_name }, format: :json end end @@ -249,7 +249,7 @@ describe Import::BitbucketController do .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json } + post :create, params: { target_namespace: 'foo/bar', new_name: test_name }, format: :json end it 'creates the namespaces' do @@ -257,7 +257,7 @@ describe Import::BitbucketController do .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - expect { post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json } } + expect { post :create, params: { target_namespace: 'foo/bar', new_name: test_name }, format: :json } .to change { Namespace.count }.by(2) end @@ -266,7 +266,7 @@ describe Import::BitbucketController do .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json } + post :create, params: { target_namespace: 'foo/bar', new_name: test_name }, format: :json expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo') end @@ -285,7 +285,7 @@ describe Import::BitbucketController do .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :json } + post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :json end it 'creates the namespaces' do @@ -293,7 +293,7 @@ describe Import::BitbucketController do .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :json } } + expect { post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :json } .to change { Namespace.count }.by(2) end end @@ -302,7 +302,7 @@ describe Import::BitbucketController do it 'returns 422 response' do other_namespace = create(:group, name: 'other_namespace') - post :create, { target_namespace: other_namespace.name, format: :json } + post :create, params: { target_namespace: other_namespace.name }, format: :json expect(response).to have_gitlab_http_status(422) end diff --git a/spec/controllers/import/bitbucket_server_controller_spec.rb b/spec/controllers/import/bitbucket_server_controller_spec.rb index db912641894..73195463a50 100644 --- a/spec/controllers/import/bitbucket_server_controller_spec.rb +++ b/spec/controllers/import/bitbucket_server_controller_spec.rb @@ -42,19 +42,19 @@ describe Import::BitbucketServerController do .to receive(:new).with(project_key, repo_slug, anything, 'my-project', user.namespace, user, anything) .and_return(double(execute: project)) - post :create, project: project_key, repository: repo_slug, format: :json + post :create, params: { project: project_key, repository: repo_slug }, format: :json expect(response).to have_gitlab_http_status(200) end it 'returns an error when an invalid project key is used' do - post :create, project: 'some&project' + post :create, params: { project: 'some&project' } expect(response).to have_gitlab_http_status(422) end it 'returns an error when an invalid repository slug is used' do - post :create, project: 'some-project', repository: 'try*this' + post :create, params: { project: 'some-project', repository: 'try*this' } expect(response).to have_gitlab_http_status(422) end @@ -62,7 +62,7 @@ describe Import::BitbucketServerController do it 'returns an error when the project cannot be found' do allow(client).to receive(:repo).with(project_key, repo_slug).and_return(nil) - post :create, project: project_key, repository: repo_slug, format: :json + post :create, params: { project: project_key, repository: repo_slug }, format: :json expect(response).to have_gitlab_http_status(422) end @@ -72,7 +72,7 @@ describe Import::BitbucketServerController do .to receive(:new).with(project_key, repo_slug, anything, 'my-project', user.namespace, user, anything) .and_return(double(execute: build(:project))) - post :create, project: project_key, repository: repo_slug, format: :json + post :create, params: { project: project_key, repository: repo_slug }, format: :json expect(response).to have_gitlab_http_status(422) end @@ -80,7 +80,7 @@ describe Import::BitbucketServerController do it "returns an error when the server can't be contacted" do expect(client).to receive(:repo).with(project_key, repo_slug).and_raise(BitbucketServer::Client::ServerError) - post :create, project: project_key, repository: repo_slug, format: :json + post :create, params: { project: project_key, repository: repo_slug }, format: :json expect(response).to have_gitlab_http_status(422) end @@ -103,7 +103,7 @@ describe Import::BitbucketServerController do end it 'sets the session variables' do - post :configure, personal_access_token: token, bitbucket_username: username, bitbucket_server_url: url + post :configure, params: { personal_access_token: token, bitbucket_username: username, bitbucket_server_url: url } expect(session[:bitbucket_server_url]).to eq(url) expect(session[:bitbucket_server_username]).to eq(username) diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index 742f4787126..a874a7d36f6 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -209,7 +209,7 @@ describe Import::GitlabController do .to receive(:new).with(gitlab_repo, nested_namespace, user, access_params) .and_return(double(execute: project)) - post :create, { target_namespace: nested_namespace.full_path, format: :json } + post :create, params: { target_namespace: nested_namespace.full_path }, format: :json end end @@ -221,7 +221,7 @@ describe Import::GitlabController do .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - post :create, { target_namespace: 'foo/bar', format: :json } + post :create, params: { target_namespace: 'foo/bar' }, format: :json end it 'creates the namespaces' do @@ -229,7 +229,7 @@ describe Import::GitlabController do .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - expect { post :create, { target_namespace: 'foo/bar', format: :json } } + expect { post :create, params: { target_namespace: 'foo/bar' }, format: :json } .to change { Namespace.count }.by(2) end @@ -238,7 +238,7 @@ describe Import::GitlabController do .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - post :create, { target_namespace: 'foo/bar', format: :json } + post :create, params: { target_namespace: 'foo/bar' }, format: :json expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo') end @@ -257,7 +257,7 @@ describe Import::GitlabController do .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - post :create, { target_namespace: 'foo/foobar/bar', format: :json } + post :create, params: { target_namespace: 'foo/foobar/bar' }, format: :json end it 'creates the namespaces' do @@ -265,7 +265,7 @@ describe Import::GitlabController do .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .and_return(double(execute: project)) - expect { post :create, { target_namespace: 'foo/foobar/bar', format: :json } } + expect { post :create, params: { target_namespace: 'foo/foobar/bar' }, format: :json } .to change { Namespace.count }.by(2) end end @@ -274,7 +274,7 @@ describe Import::GitlabController do it 'returns 422 response' do other_namespace = create(:group, name: 'other_namespace') - post :create, { target_namespace: other_namespace.name, format: :json } + post :create, params: { target_namespace: other_namespace.name }, format: :json expect(response).to have_gitlab_http_status(422) end diff --git a/spec/controllers/import/gitlab_projects_controller_spec.rb b/spec/controllers/import/gitlab_projects_controller_spec.rb index cbd1a112602..55bd8ae7182 100644 --- a/spec/controllers/import/gitlab_projects_controller_spec.rb +++ b/spec/controllers/import/gitlab_projects_controller_spec.rb @@ -12,14 +12,14 @@ describe Import::GitlabProjectsController do describe 'POST create' do context 'with an invalid path' do it 'redirects with an error' do - post :create, namespace_id: namespace.id, path: '/test', file: file + post :create, params: { namespace_id: namespace.id, path: '/test', file: file } expect(flash[:alert]).to start_with('Project could not be imported') expect(response).to have_gitlab_http_status(302) end it 'redirects with an error when a relative path is used' do - post :create, namespace_id: namespace.id, path: '../test', file: file + post :create, params: { namespace_id: namespace.id, path: '../test', file: file } expect(flash[:alert]).to start_with('Project could not be imported') expect(response).to have_gitlab_http_status(302) @@ -28,7 +28,7 @@ describe Import::GitlabProjectsController do context 'with a valid path' do it 'redirects to the new project path' do - post :create, namespace_id: namespace.id, path: 'test', file: file + post :create, params: { namespace_id: namespace.id, path: 'test', file: file } expect(flash[:notice]).to include('is being imported') expect(response).to have_gitlab_http_status(302) diff --git a/spec/controllers/import/google_code_controller_spec.rb b/spec/controllers/import/google_code_controller_spec.rb index 0763492d88a..3e5ed2afd93 100644 --- a/spec/controllers/import/google_code_controller_spec.rb +++ b/spec/controllers/import/google_code_controller_spec.rb @@ -12,7 +12,7 @@ describe Import::GoogleCodeController do describe "POST callback" do it "stores Google Takeout dump list in session" do - post :callback, dump_file: dump_file + post :callback, params: { dump_file: dump_file } expect(session[:google_code_dump]).to be_a(Hash) expect(session[:google_code_dump]["kind"]).to eq("projecthosting#user") diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index 6c09ca7dc66..7bbaf36e4df 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -12,7 +12,7 @@ describe InvitesController do describe 'GET #accept' do it 'accepts user' do - get :accept, id: token + get :accept, params: { id: token } member.reload expect(response).to have_gitlab_http_status(302) @@ -23,7 +23,7 @@ describe InvitesController do describe 'GET #decline' do it 'declines user' do - get :decline, id: token + get :decline, params: { id: token } expect {member.reload}.to raise_error ActiveRecord::RecordNotFound expect(response).to have_gitlab_http_status(302) diff --git a/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb index 87c10a86cdd..c9d36a16008 100644 --- a/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb +++ b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb @@ -11,7 +11,7 @@ describe Ldap::OmniauthCallbacksController do it 'respects remember me checkbox' do expect do - post provider, remember_me: '1' + post provider, params: { remember_me: '1' } end.to change { user.reload.remember_created_at }.from(nil) end @@ -19,7 +19,7 @@ describe Ldap::OmniauthCallbacksController do let(:user) { create(:omniauth_user, :two_factor_via_otp, extern_uid: uid, provider: provider) } it 'passes remember_me to the Devise view' do - post provider, remember_me: '1' + post provider, params: { remember_me: '1' } expect(assigns[:user].remember_me).to eq '1' end diff --git a/spec/controllers/notification_settings_controller_spec.rb b/spec/controllers/notification_settings_controller_spec.rb index a3356a86d4b..cf52ce834b6 100644 --- a/spec/controllers/notification_settings_controller_spec.rb +++ b/spec/controllers/notification_settings_controller_spec.rb @@ -13,8 +13,10 @@ describe NotificationSettingsController do context 'when not authorized' do it 'redirects to sign in page' do post :create, - project_id: project.id, - notification_setting: { level: :participating } + params: { + project_id: project.id, + notification_setting: { level: :participating } + } expect(response).to redirect_to(new_user_session_path) end @@ -41,8 +43,10 @@ describe NotificationSettingsController do it 'creates notification setting' do post :create, - project_id: project.id, - notification_setting: { level: :participating } + params: { + project_id: project.id, + notification_setting: { level: :participating } + } expect(response.status).to eq 200 expect(notification_setting.level).to eq("participating") @@ -54,8 +58,10 @@ describe NotificationSettingsController do context 'with custom settings' do it 'creates notification setting' do post :create, - project_id: project.id, - notification_setting: { level: :custom }.merge(custom_events) + params: { + project_id: project.id, + notification_setting: { level: :custom }.merge(custom_events) + } expect(response.status).to eq 200 expect(notification_setting.level).to eq("custom") @@ -72,8 +78,10 @@ describe NotificationSettingsController do it 'creates notification setting' do post :create, - namespace_id: group.id, - notification_setting: { level: :watch } + params: { + namespace_id: group.id, + notification_setting: { level: :watch } + } expect(response.status).to eq 200 expect(notification_setting.level).to eq("watch") @@ -85,8 +93,10 @@ describe NotificationSettingsController do context 'with custom settings' do it 'creates notification setting' do post :create, - namespace_id: group.id, - notification_setting: { level: :custom }.merge(custom_events) + params: { + namespace_id: group.id, + notification_setting: { level: :custom }.merge(custom_events) + } expect(response.status).to eq 200 expect(notification_setting.level).to eq("custom") @@ -108,8 +118,10 @@ describe NotificationSettingsController do it 'returns 404' do post :create, - project_id: private_project.id, - notification_setting: { level: :participating } + params: { + project_id: private_project.id, + notification_setting: { level: :participating } + } expect(response).to have_gitlab_http_status(404) end @@ -122,8 +134,10 @@ describe NotificationSettingsController do context 'when not authorized' do it 'redirects to sign in page' do put :update, - id: notification_setting, - notification_setting: { level: :participating } + params: { + id: notification_setting, + notification_setting: { level: :participating } + } expect(response).to redirect_to(new_user_session_path) end @@ -136,8 +150,10 @@ describe NotificationSettingsController do it 'returns success' do put :update, - id: notification_setting, - notification_setting: { level: :participating } + params: { + id: notification_setting, + notification_setting: { level: :participating } + } expect(response.status).to eq 200 end @@ -153,8 +169,10 @@ describe NotificationSettingsController do it 'returns success' do put :update, - id: notification_setting, - notification_setting: { level: :participating, events: custom_events } + params: { + id: notification_setting, + notification_setting: { level: :participating, events: custom_events } + } expect(response.status).to eq 200 end @@ -170,8 +188,10 @@ describe NotificationSettingsController do it 'returns 404' do put :update, - id: notification_setting, - notification_setting: { level: :participating } + params: { + id: notification_setting, + notification_setting: { level: :participating } + } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb index b4219856fc0..caf2b87428b 100644 --- a/spec/controllers/oauth/applications_controller_spec.rb +++ b/spec/controllers/oauth/applications_controller_spec.rb @@ -26,7 +26,7 @@ describe Oauth::ApplicationsController do describe 'POST #create' do it 'creates an application' do - post :create, oauth_params + post :create, params: oauth_params expect(response).to have_gitlab_http_status(302) expect(response).to redirect_to(oauth_application_path(Doorkeeper::Application.last)) @@ -35,7 +35,7 @@ describe Oauth::ApplicationsController do it 'redirects back to profile page if OAuth applications are disabled' do disable_user_oauth - post :create, oauth_params + post :create, params: oauth_params expect(response).to have_gitlab_http_status(302) expect(response).to redirect_to(profile_path) @@ -52,7 +52,7 @@ describe Oauth::ApplicationsController do } } - post :create, invalid_uri_params + post :create, params: invalid_uri_params expect(response.body).to include 'Redirect URI is forbidden by the server' end diff --git a/spec/controllers/oauth/authorizations_controller_spec.rb b/spec/controllers/oauth/authorizations_controller_spec.rb index 8c10ea53a7a..cc8fa2c01b4 100644 --- a/spec/controllers/oauth/authorizations_controller_spec.rb +++ b/spec/controllers/oauth/authorizations_controller_spec.rb @@ -30,7 +30,7 @@ describe Oauth::AuthorizationsController do render_views it 'returns 200 code and renders view' do - get :new, params + get :new, params: params expect(response).to have_gitlab_http_status(200) expect(response).to render_template('doorkeeper/authorizations/new') @@ -40,7 +40,7 @@ describe Oauth::AuthorizationsController do application.update(trusted: true) request.session['user_return_to'] = 'http://example.com' - get :new, params + get :new, params: params expect(request.session['user_return_to']).to be_nil expect(response).to have_gitlab_http_status(302) @@ -57,7 +57,7 @@ describe Oauth::AuthorizationsController do end it 'authorizes the request and redirects' do - get :new, params + get :new, params: params expect(request.session['user_return_to']).to be_nil expect(response).to have_gitlab_http_status(302) diff --git a/spec/controllers/passwords_controller_spec.rb b/spec/controllers/passwords_controller_spec.rb index 4d31cfedbd2..0af55cf3408 100644 --- a/spec/controllers/passwords_controller_spec.rb +++ b/spec/controllers/passwords_controller_spec.rb @@ -22,7 +22,7 @@ describe PasswordsController do let(:user) { create(:omniauth_user, provider: 'ldapmain', email: 'ldapuser@gitlab.com') } it 'prevents a password reset' do - post :create, user: { email: user.email } + post :create, params: { user: { email: user.email } } expect(flash[:alert]).to eq 'Password authentication is unavailable.' end diff --git a/spec/controllers/profiles/accounts_controller_spec.rb b/spec/controllers/profiles/accounts_controller_spec.rb index f8d9d7e39ee..bb2ab27e2dd 100644 --- a/spec/controllers/profiles/accounts_controller_spec.rb +++ b/spec/controllers/profiles/accounts_controller_spec.rb @@ -9,7 +9,7 @@ describe Profiles::AccountsController do end it 'renders 404 if someone tries to unlink a non existent provider' do - delete :unlink, provider: 'github' + delete :unlink, params: { provider: 'github' } expect(response).to have_gitlab_http_status(404) end @@ -21,7 +21,7 @@ describe Profiles::AccountsController do it "does not allow to unlink connected account" do identity = user.identities.last - delete :unlink, provider: provider.to_s + delete :unlink, params: { provider: provider.to_s } expect(response).to have_gitlab_http_status(302) expect(user.reload.identities).to include(identity) @@ -36,7 +36,7 @@ describe Profiles::AccountsController do it 'allows to unlink connected account' do identity = user.identities.last - delete :unlink, provider: provider.to_s + delete :unlink, params: { provider: provider.to_s } expect(response).to have_gitlab_http_status(302) expect(user.reload.identities).not_to include(identity) diff --git a/spec/controllers/profiles/emails_controller_spec.rb b/spec/controllers/profiles/emails_controller_spec.rb index ecf14aad54f..a8a1f96befe 100644 --- a/spec/controllers/profiles/emails_controller_spec.rb +++ b/spec/controllers/profiles/emails_controller_spec.rb @@ -11,7 +11,7 @@ describe Profiles::EmailsController do let(:email_params) { { email: "add_email@example.com" } } it 'sends an email confirmation' do - expect { post(:create, { email: email_params }) }.to change { ActionMailer::Base.deliveries.size } + expect { post(:create, params: { email: email_params }) }.to change { ActionMailer::Base.deliveries.size } expect(ActionMailer::Base.deliveries.last.to).to eq [email_params[:email]] expect(ActionMailer::Base.deliveries.last.subject).to match "Confirmation instructions" end @@ -23,13 +23,13 @@ describe Profiles::EmailsController do it 'resends an email confirmation' do email = user.emails.create(email: 'add_email@example.com') - expect { put(:resend_confirmation_instructions, { id: email }) }.to change { ActionMailer::Base.deliveries.size } + expect { put(:resend_confirmation_instructions, params: { id: email }) }.to change { ActionMailer::Base.deliveries.size } expect(ActionMailer::Base.deliveries.last.to).to eq [email_params[:email]] expect(ActionMailer::Base.deliveries.last.subject).to match "Confirmation instructions" end it 'unable to resend an email confirmation' do - expect { put(:resend_confirmation_instructions, { id: 1 }) }.not_to change { ActionMailer::Base.deliveries.size } + expect { put(:resend_confirmation_instructions, params: { id: 1 }) }.not_to change { ActionMailer::Base.deliveries.size } end end end diff --git a/spec/controllers/profiles/keys_controller_spec.rb b/spec/controllers/profiles/keys_controller_spec.rb index 685db8488f0..5e2cc82bd8c 100644 --- a/spec/controllers/profiles/keys_controller_spec.rb +++ b/spec/controllers/profiles/keys_controller_spec.rb @@ -6,7 +6,7 @@ describe Profiles::KeysController do describe "#get_keys" do describe "non existent user" do it "does not generally work" do - get :get_keys, username: 'not-existent' + get :get_keys, params: { username: 'not-existent' } expect(response).not_to be_success end @@ -14,19 +14,19 @@ describe Profiles::KeysController do describe "user with no keys" do it "does generally work" do - get :get_keys, username: user.username + get :get_keys, params: { username: user.username } expect(response).to be_success end it "renders all keys separated with a new line" do - get :get_keys, username: user.username + get :get_keys, params: { username: user.username } expect(response.body).to eq("") end it "responds with text/plain content type" do - get :get_keys, username: user.username + get :get_keys, params: { username: user.username } expect(response.content_type).to eq("text/plain") end end @@ -37,13 +37,13 @@ describe Profiles::KeysController do let!(:deploy_key) { create(:deploy_key, user: user) } it "does generally work" do - get :get_keys, username: user.username + get :get_keys, params: { username: user.username } expect(response).to be_success end it "renders all non deploy keys separated with a new line" do - get :get_keys, username: user.username + get :get_keys, params: { username: user.username } expect(response.body).not_to eq('') expect(response.body).to eq(user.all_ssh_keys.join("\n")) @@ -55,22 +55,16 @@ describe Profiles::KeysController do end it "does not render the comment of the key" do - get :get_keys, username: user.username + get :get_keys, params: { username: user.username } expect(response.body).not_to match(/dummy@gitlab.com/) end it "responds with text/plain content type" do - get :get_keys, username: user.username + get :get_keys, params: { username: user.username } expect(response.content_type).to eq("text/plain") end - - it "responds with attachment content disposition" do - get :get_keys, username: user.username - - expect(response.headers['Content-Disposition']).to eq('attachment') - end end end end diff --git a/spec/controllers/profiles/notifications_controller_spec.rb b/spec/controllers/profiles/notifications_controller_spec.rb index b97cdd4d489..1b76446a0cf 100644 --- a/spec/controllers/profiles/notifications_controller_spec.rb +++ b/spec/controllers/profiles/notifications_controller_spec.rb @@ -24,7 +24,7 @@ describe Profiles::NotificationsController do it 'updates only permitted attributes' do sign_in(user) - put :update, user: { notification_email: 'new@example.com', notified_of_own_activity: true, admin: true } + put :update, params: { user: { notification_email: 'new@example.com', notified_of_own_activity: true, admin: true } } user.reload expect(user.notification_email).to eq('new@example.com') @@ -36,7 +36,7 @@ describe Profiles::NotificationsController do it 'shows an error message if the params are invalid' do sign_in(user) - put :update, user: { notification_email: '' } + put :update, params: { user: { notification_email: '' } } expect(user.reload.notification_email).to eq('original@example.com') expect(controller).to set_flash[:alert].to('Failed to save new settings') diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb index f5860d4296b..021bf2429e3 100644 --- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb +++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb @@ -17,7 +17,7 @@ describe Profiles::PersonalAccessTokensController do name = 'My PAT' scopes = %w[api read_user] - post :create, personal_access_token: token_attributes.merge(scopes: scopes, name: name) + post :create, params: { personal_access_token: token_attributes.merge(scopes: scopes, name: name) } expect(created_token).not_to be_nil expect(created_token.name).to eq(name) @@ -28,7 +28,7 @@ describe Profiles::PersonalAccessTokensController do it "allows creation of a token with an expiry date" do expires_at = 5.days.from_now.to_date - post :create, personal_access_token: token_attributes.merge(expires_at: expires_at) + post :create, params: { personal_access_token: token_attributes.merge(expires_at: expires_at) } expect(created_token).not_to be_nil expect(created_token.expires_at).to eq(expires_at) diff --git a/spec/controllers/profiles/preferences_controller_spec.rb b/spec/controllers/profiles/preferences_controller_spec.rb index a66b4ab0902..012f016b091 100644 --- a/spec/controllers/profiles/preferences_controller_spec.rb +++ b/spec/controllers/profiles/preferences_controller_spec.rb @@ -29,7 +29,7 @@ describe Profiles::PreferencesController do theme_id: '1' ) - patch :update, user: params, format: format + patch :update, params: { user: params }, format: format end context 'on successful update' do @@ -45,7 +45,7 @@ describe Profiles::PreferencesController do theme_id: '2' }.with_indifferent_access - expect(user).to receive(:assign_attributes).with(prefs) + expect(user).to receive(:assign_attributes).with(ActionController::Parameters.new(prefs).permit!) expect(user).to receive(:save) go params: prefs diff --git a/spec/controllers/profiles/two_factor_auths_controller_spec.rb b/spec/controllers/profiles/two_factor_auths_controller_spec.rb index d08d0018b35..0151a434998 100644 --- a/spec/controllers/profiles/two_factor_auths_controller_spec.rb +++ b/spec/controllers/profiles/two_factor_auths_controller_spec.rb @@ -32,7 +32,7 @@ describe Profiles::TwoFactorAuthsController do let(:pin) { 'pin-code' } def go - post :create, pin_code: pin + post :create, params: { pin_code: pin } end context 'with valid pin' do diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb index 360c536c667..11cb59aa12a 100644 --- a/spec/controllers/profiles_controller_spec.rb +++ b/spec/controllers/profiles_controller_spec.rb @@ -9,7 +9,7 @@ describe ProfilesController, :request_store do expect do post :update, - user: { password: 'hello12345', password_confirmation: 'hello12345' } + params: { user: { password: 'hello12345', password_confirmation: 'hello12345' } } end.not_to change { user.reload.encrypted_password } expect(response.status).to eq(302) @@ -21,7 +21,7 @@ describe ProfilesController, :request_store do sign_in(user) put :update, - user: { email: "john@gmail.com", name: "John" } + params: { user: { email: "john@gmail.com", name: "John" } } user.reload @@ -35,7 +35,7 @@ describe ProfilesController, :request_store do sign_in(user) put :update, - user: { email: "john@gmail.com", name: "John" } + params: { user: { email: "john@gmail.com", name: "John" } } user.reload @@ -52,7 +52,7 @@ describe ProfilesController, :request_store do sign_in(ldap_user) put :update, - user: { email: "john@gmail.com", name: "John" } + params: { user: { email: "john@gmail.com", name: "John" } } ldap_user.reload @@ -69,7 +69,7 @@ describe ProfilesController, :request_store do sign_in(ldap_user) put :update, - user: { email: "john@gmail.com", name: "John", location: "City, Country" } + params: { user: { email: "john@gmail.com", name: "John", location: "City, Country" } } ldap_user.reload @@ -82,7 +82,7 @@ describe ProfilesController, :request_store do it 'allows setting a user status' do sign_in(user) - put :update, user: { status: { message: 'Working hard!' } } + put :update, params: { user: { status: { message: 'Working hard!' } } } expect(user.reload.status.message).to eq('Working hard!') expect(response).to have_gitlab_http_status(302) @@ -98,7 +98,7 @@ describe ProfilesController, :request_store do sign_in(user) put :update_username, - user: { username: new_username } + params: { user: { username: new_username } } user.reload @@ -110,7 +110,9 @@ describe ProfilesController, :request_store do sign_in(user) put :update_username, - user: { username: new_username }, + params: { + user: { username: new_username } + }, format: :json expect(response.status).to eq(200) @@ -121,7 +123,9 @@ describe ProfilesController, :request_store do sign_in(user) put :update_username, - user: { username: 'invalid username.git' }, + params: { + user: { username: 'invalid username.git' } + }, format: :json expect(response.status).to eq(422) @@ -131,7 +135,7 @@ describe ProfilesController, :request_store do it 'raises a correct error when the username is missing' do sign_in(user) - expect { put :update_username, user: { gandalf: 'you shall not pass' } } + expect { put :update_username, params: { user: { gandalf: 'you shall not pass' } } } .to raise_error(ActionController::ParameterMissing) end @@ -142,7 +146,7 @@ describe ProfilesController, :request_store do sign_in(user) put :update_username, - user: { username: new_username } + params: { user: { username: new_username } } user.reload @@ -160,7 +164,7 @@ describe ProfilesController, :request_store do sign_in(user) put :update_username, - user: { username: new_username } + params: { user: { username: new_username } } user.reload diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb index b3c8d6a954e..bd10de45b67 100644 --- a/spec/controllers/projects/artifacts_controller_spec.rb +++ b/spec/controllers/projects/artifacts_controller_spec.rb @@ -22,7 +22,7 @@ describe Projects::ArtifactsController do def download_artifact(extra_params = {}) params = { namespace_id: project.namespace, project_id: project, job_id: job }.merge(extra_params) - get :download, params + get :download, params: params end context 'when no file type is supplied' do @@ -86,7 +86,7 @@ describe Projects::ArtifactsController do describe 'GET browse' do context 'when the directory exists' do it 'renders the browse view' do - get :browse, namespace_id: project.namespace, project_id: project, job_id: job, path: 'other_artifacts_0.1.2' + get :browse, params: { namespace_id: project.namespace, project_id: project, job_id: job, path: 'other_artifacts_0.1.2' } expect(response).to render_template('projects/artifacts/browse') end @@ -94,7 +94,7 @@ describe Projects::ArtifactsController do context 'when the directory does not exist' do it 'responds Not Found' do - get :browse, namespace_id: project.namespace, project_id: project, job_id: job, path: 'unknown' + get :browse, params: { namespace_id: project.namespace, project_id: project, job_id: job, path: 'unknown' } expect(response).to be_not_found end @@ -113,7 +113,7 @@ describe Projects::ArtifactsController do context 'when the file exists' do it 'renders the file view' do - get :file, namespace_id: project.namespace, project_id: project, job_id: job, path: 'ci_artifacts.txt' + get :file, params: { namespace_id: project.namespace, project_id: project, job_id: job, path: 'ci_artifacts.txt' } expect(response).to have_gitlab_http_status(302) end @@ -121,7 +121,7 @@ describe Projects::ArtifactsController do context 'when the file does not exist' do it 'responds Not Found' do - get :file, namespace_id: project.namespace, project_id: project, job_id: job, path: 'unknown' + get :file, params: { namespace_id: project.namespace, project_id: project, job_id: job, path: 'unknown' } expect(response).to be_not_found end @@ -131,7 +131,7 @@ describe Projects::ArtifactsController do context 'when the file is served through Rails' do context 'when the file exists' do it 'renders the file view' do - get :file, namespace_id: project.namespace, project_id: project, job_id: job, path: 'ci_artifacts.txt' + get :file, params: { namespace_id: project.namespace, project_id: project, job_id: job, path: 'ci_artifacts.txt' } expect(response).to have_gitlab_http_status(:ok) expect(response).to render_template('projects/artifacts/file') @@ -140,7 +140,7 @@ describe Projects::ArtifactsController do context 'when the file does not exist' do it 'responds Not Found' do - get :file, namespace_id: project.namespace, project_id: project, job_id: job, path: 'unknown' + get :file, params: { namespace_id: project.namespace, project_id: project, job_id: job, path: 'unknown' } expect(response).to be_not_found end @@ -159,7 +159,7 @@ describe Projects::ArtifactsController do end it 'does not redirect the request' do - get :file, namespace_id: private_project.namespace, project_id: private_project, job_id: job, path: 'ci_artifacts.txt' + get :file, params: { namespace_id: private_project.namespace, project_id: private_project, job_id: job, path: 'ci_artifacts.txt' } expect(response).to have_gitlab_http_status(:ok) expect(response).to render_template('projects/artifacts/file') @@ -168,7 +168,7 @@ describe Projects::ArtifactsController do end describe 'GET raw' do - subject { get(:raw, namespace_id: project.namespace, project_id: project, job_id: job, path: path) } + subject { get(:raw, params: { namespace_id: project.namespace, project_id: project, job_id: job, path: path }) } context 'when the file exists' do let(:path) { 'ci_artifacts.txt' } @@ -239,7 +239,7 @@ describe Projects::ArtifactsController do context 'has no such ref' do before do - get :latest_succeeded, params_from_ref('TAIL', job.name) + get :latest_succeeded, params: params_from_ref('TAIL', job.name) end it_behaves_like 'not found' @@ -247,7 +247,7 @@ describe Projects::ArtifactsController do context 'has no such job' do before do - get :latest_succeeded, params_from_ref(pipeline.ref, 'NOBUILD') + get :latest_succeeded, params: params_from_ref(pipeline.ref, 'NOBUILD') end it_behaves_like 'not found' @@ -255,7 +255,7 @@ describe Projects::ArtifactsController do context 'has no path' do before do - get :latest_succeeded, params_from_ref(pipeline.sha, job.name, '') + get :latest_succeeded, params: params_from_ref(pipeline.sha, job.name, '') end it_behaves_like 'not found' @@ -276,7 +276,7 @@ describe Projects::ArtifactsController do pipeline.update(ref: 'master', sha: project.commit('master').sha) - get :latest_succeeded, params_from_ref('master') + get :latest_succeeded, params: params_from_ref('master') end it_behaves_like 'redirect to the job' @@ -287,7 +287,7 @@ describe Projects::ArtifactsController do pipeline.update(ref: 'improve/awesome', sha: project.commit('improve/awesome').sha) - get :latest_succeeded, params_from_ref('improve/awesome') + get :latest_succeeded, params: params_from_ref('improve/awesome') end it_behaves_like 'redirect to the job' @@ -298,7 +298,7 @@ describe Projects::ArtifactsController do pipeline.update(ref: 'improve/awesome', sha: project.commit('improve/awesome').sha) - get :latest_succeeded, params_from_ref('improve/awesome', job.name, 'file/README.md') + get :latest_succeeded, params: params_from_ref('improve/awesome', job.name, 'file/README.md') end it 'redirects' do diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb index 5a77a7ac06f..95b7ae5885a 100644 --- a/spec/controllers/projects/avatars_controller_spec.rb +++ b/spec/controllers/projects/avatars_controller_spec.rb @@ -8,7 +8,7 @@ describe Projects::AvatarsController do end describe 'GET #show' do - subject { get :show, namespace_id: project.namespace, project_id: project } + subject { get :show, params: { namespace_id: project.namespace, project_id: project } } context 'when repository has no avatar' do it 'shows 404' do @@ -26,37 +26,13 @@ describe Projects::AvatarsController do context 'when the avatar is stored in the repository' do let(:filepath) { 'files/images/logo-white.png' } - context 'when feature flag workhorse_set_content_type is' do - before do - stub_feature_flags(workhorse_set_content_type: flag_value) - end + it 'sends the avatar' do + subject - context 'enabled' do - let(:flag_value) { true } - - it 'sends the avatar' do - subject - - expect(response).to have_gitlab_http_status(200) - expect(response.header['Content-Disposition']).to eq('inline') - expect(response.header['Content-Type']).to eq 'image/png' - expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - end - end - - context 'disabled' do - let(:flag_value) { false } - - it 'sends the avatar' do - subject - - expect(response).to have_gitlab_http_status(200) - expect(response.header['Content-Type']).to eq('image/png') - expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq nil - end - end + expect(response).to have_gitlab_http_status(200) + expect(response.header['Content-Disposition']).to eq('inline') + expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') + expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" end end @@ -71,7 +47,7 @@ describe Projects::AvatarsController do describe 'DELETE #destroy' do it 'removes avatar from DB by calling destroy' do - delete :destroy, namespace_id: project.namespace.id, project_id: project.id + delete :destroy, params: { namespace_id: project.namespace.id, project_id: project.id } expect(project.avatar.present?).to be_falsey expect(project).to be_valid diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb index dfe34171b55..2556bc3ae50 100644 --- a/spec/controllers/projects/badges_controller_spec.rb +++ b/spec/controllers/projects/badges_controller_spec.rb @@ -23,6 +23,6 @@ describe Projects::BadgesController do end def get_badge(badge) - get badge, namespace_id: project.namespace.to_param, project_id: project, ref: pipeline.ref, format: :svg + get badge, params: { namespace_id: project.namespace.to_param, project_id: project, ref: pipeline.ref }, format: :svg end end diff --git a/spec/controllers/projects/blame_controller_spec.rb b/spec/controllers/projects/blame_controller_spec.rb index fe4c4863717..eb110ea0002 100644 --- a/spec/controllers/projects/blame_controller_spec.rb +++ b/spec/controllers/projects/blame_controller_spec.rb @@ -16,9 +16,11 @@ describe Projects::BlameController do before do get(:show, - namespace_id: project.namespace, - project_id: project, - id: id) + params: { + namespace_id: project.namespace, + project_id: project, + id: id + }) end context "valid file" do diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb index 9fc6af6a045..38957e96798 100644 --- a/spec/controllers/projects/blob_controller_spec.rb +++ b/spec/controllers/projects/blob_controller_spec.rb @@ -11,9 +11,11 @@ describe Projects::BlobController do context 'with file path' do before do get(:show, - namespace_id: project.namespace, - project_id: project, - id: id) + params: { + namespace_id: project.namespace, + project_id: project, + id: id + }) end context "valid branch, valid file" do @@ -48,9 +50,11 @@ describe Projects::BlobController do before do get(:show, - namespace_id: project.namespace, - project_id: project, - id: id, + params: { + namespace_id: project.namespace, + project_id: project, + id: id + }, format: :json) end @@ -66,11 +70,13 @@ describe Projects::BlobController do before do get(:show, - namespace_id: project.namespace, - project_id: project, - id: id, - format: :json, - viewer: 'none') + params: { + namespace_id: project.namespace, + project_id: project, + id: id, + viewer: 'none' + }, + format: :json) end it do @@ -84,9 +90,11 @@ describe Projects::BlobController do context 'with tree path' do before do get(:show, - namespace_id: project.namespace, - project_id: project, - id: id) + params: { + namespace_id: project.namespace, + project_id: project, + id: id + }) controller.instance_variable_set(:@blob, nil) end @@ -109,7 +117,7 @@ describe Projects::BlobController do params = { namespace_id: project.namespace, project_id: project, id: 'master/CHANGELOG' } - get :diff, params.merge(opts) + get :diff, params: params.merge(opts) end before do @@ -200,7 +208,7 @@ describe Projects::BlobController do context 'anonymous' do before do - get :edit, default_params + get :edit, params: default_params end it 'redirects to sign in and returns' do @@ -213,7 +221,7 @@ describe Projects::BlobController do before do sign_in(guest) - get :edit, default_params + get :edit, params: default_params end it 'redirects to blob show' do @@ -227,7 +235,7 @@ describe Projects::BlobController do before do project.add_developer(developer) sign_in(developer) - get :edit, default_params + get :edit, params: default_params end it 'redirects to blob show' do @@ -241,7 +249,7 @@ describe Projects::BlobController do before do project.add_maintainer(maintainer) sign_in(maintainer) - get :edit, default_params + get :edit, params: default_params end it 'redirects to blob show' do @@ -274,7 +282,7 @@ describe Projects::BlobController do end it 'redirects to blob' do - put :update, default_params + put :update, params: default_params expect(response).to redirect_to(blob_after_edit_path) end @@ -284,7 +292,7 @@ describe Projects::BlobController do let(:mr_params) { default_params.merge(from_merge_request_iid: merge_request.iid) } it 'redirects to MR diff' do - put :update, mr_params + put :update, params: mr_params after_edit_path = diffs_project_merge_request_path(project, merge_request) file_anchor = "##{Digest::SHA1.hexdigest('CHANGELOG')}" @@ -298,7 +306,7 @@ describe Projects::BlobController do end it "it redirect to blob" do - put :update, mr_params + put :update, params: mr_params expect(response).to redirect_to(blob_after_edit_path) end @@ -320,7 +328,7 @@ describe Projects::BlobController do end it 'redirects to blob' do - put :update, default_params + put :update, params: default_params expect(response).to redirect_to(project_blob_path(forked_project, 'master/CHANGELOG')) end @@ -331,7 +339,7 @@ describe Projects::BlobController do default_params[:branch_name] = "fork-test-1" default_params[:create_merge_request] = 1 - put :update, default_params + put :update, params: default_params expect(response).to redirect_to( project_new_merge_request_path( @@ -374,7 +382,7 @@ describe Projects::BlobController do let(:after_delete_path) { project_tree_path(project, 'master/files') } it 'redirects to the sub directory' do - delete :destroy, default_params + delete :destroy, params: default_params expect(response).to redirect_to(after_delete_path) end @@ -393,7 +401,7 @@ describe Projects::BlobController do end it 'redirects to the project root' do - delete :destroy, default_params + delete :destroy, params: default_params expect(response).to redirect_to(project_root_path) end @@ -413,7 +421,7 @@ describe Projects::BlobController do let(:after_delete_path) { project_tree_path(project, 'binary-encoding') } it 'redirects to the project root of the branch' do - delete :destroy, default_params + delete :destroy, params: default_params expect(response).to redirect_to(after_delete_path) end diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb index 8d503f6ad32..09199067024 100644 --- a/spec/controllers/projects/boards_controller_spec.rb +++ b/spec/controllers/projects/boards_controller_spec.rb @@ -121,8 +121,10 @@ describe Projects::BoardsController do end def list_boards(format: :html) - get :index, namespace_id: project.namespace, - project_id: project, + get :index, params: { + namespace_id: project.namespace, + project_id: project + }, format: format end end @@ -207,9 +209,11 @@ describe Projects::BoardsController do end def read_board(board:, format: :html) - get :show, namespace_id: project.namespace, - project_id: project, - id: board.to_param, + get :show, params: { + namespace_id: project.namespace, + project_id: project, + id: board.to_param + }, format: format end end diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index 31471cde420..02b3d5269a6 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -22,10 +22,12 @@ describe Projects::BranchesController do sign_in(user) post :create, - namespace_id: project.namespace, - project_id: project, - branch_name: branch, - ref: ref + params: { + namespace_id: project.namespace, + project_id: project, + branch_name: branch, + ref: ref + } end context "valid branch name, valid source" do @@ -76,10 +78,12 @@ describe Projects::BranchesController do it 'redirects' do post :create, - namespace_id: project.namespace, - project_id: project, - branch_name: branch, - issue_iid: issue.iid + params: { + namespace_id: project.namespace, + project_id: project, + branch_name: branch, + issue_iid: issue.iid + } expect(subject) .to redirect_to("/#{project.full_path}/tree/1-feature-branch") @@ -89,10 +93,12 @@ describe Projects::BranchesController do expect(SystemNoteService).to receive(:new_issue_branch).with(issue, project, user, "1-feature-branch") post :create, - namespace_id: project.namespace, - project_id: project, - branch_name: branch, - issue_iid: issue.iid + params: { + namespace_id: project.namespace, + project_id: project, + branch_name: branch, + issue_iid: issue.iid + } end context 'repository-less project' do @@ -105,10 +111,12 @@ describe Projects::BranchesController do expect(SystemNoteService).to receive(:new_issue_branch).and_return(true) post :create, - namespace_id: project.namespace.to_param, - project_id: project.to_param, - branch_name: branch, - issue_iid: issue.iid + params: { + namespace_id: project.namespace.to_param, + project_id: project.to_param, + branch_name: branch, + issue_iid: issue.iid + } expect(response).to redirect_to project_tree_path(project, branch) end @@ -121,10 +129,12 @@ describe Projects::BranchesController do expect(SystemNoteService).to receive(:new_issue_branch).and_return(true) post :create, - namespace_id: project.namespace.to_param, - project_id: project.to_param, - branch_name: branch, - issue_iid: issue.iid + params: { + namespace_id: project.namespace.to_param, + project_id: project.to_param, + branch_name: branch, + issue_iid: issue.iid + } expect(response.location).to include(project_new_blob_path(project, branch)) expect(response).to have_gitlab_http_status(302) @@ -156,10 +166,12 @@ describe Projects::BranchesController do expect(SystemNoteService).to receive(:new_issue_branch).and_return(true) post :create, - namespace_id: project.namespace.to_param, - project_id: project.to_param, - branch_name: branch, - issue_iid: issue.iid + params: { + namespace_id: project.namespace.to_param, + project_id: project.to_param, + branch_name: branch, + issue_iid: issue.iid + } expect(response.location).to include(project_new_blob_path(project, branch)) expect(response).to have_gitlab_http_status(302) @@ -173,10 +185,12 @@ describe Projects::BranchesController do expect(SystemNoteService).not_to receive(:new_issue_branch) post :create, - namespace_id: project.namespace, - project_id: project, - branch_name: branch, - issue_iid: issue.iid + params: { + namespace_id: project.namespace, + project_id: project, + branch_name: branch, + issue_iid: issue.iid + } end end @@ -191,10 +205,12 @@ describe Projects::BranchesController do expect(SystemNoteService).not_to receive(:new_issue_branch) post :create, - namespace_id: project.namespace, - project_id: project, - branch_name: branch, - issue_iid: issue.iid + params: { + namespace_id: project.namespace, + project_id: project, + branch_name: branch, + issue_iid: issue.iid + } end end end @@ -228,11 +244,14 @@ describe Projects::BranchesController do end def create_branch(name:, ref:) - post :create, namespace_id: project.namespace.to_param, - project_id: project.to_param, - branch_name: name, - ref: ref, - format: :json + post :create, + format: :json, + params: { + namespace_id: project.namespace.to_param, + project_id: project.to_param, + branch_name: name, + ref: ref + } end end @@ -246,9 +265,11 @@ describe Projects::BranchesController do it 'returns 303' do post :destroy, format: :html, - id: 'foo/bar/baz', - namespace_id: project.namespace, - project_id: project + params: { + id: 'foo/bar/baz', + namespace_id: project.namespace, + project_id: project + } expect(response).to have_gitlab_http_status(303) end @@ -261,10 +282,12 @@ describe Projects::BranchesController do sign_in(user) post :destroy, - format: format, - id: branch, - namespace_id: project.namespace, - project_id: project + format: format, + params: { + id: branch, + namespace_id: project.namespace, + project_id: project + } end context 'as JS' do @@ -359,8 +382,10 @@ describe Projects::BranchesController do describe "DELETE destroy_all_merged" do def destroy_all_merged delete :destroy_all_merged, - namespace_id: project.namespace, - project_id: project + params: { + namespace_id: project.namespace, + project_id: project + } end context 'when user is allowed to push' do @@ -404,10 +429,12 @@ describe Projects::BranchesController do context 'when rendering a JSON format' do it 'filters branches by name' do get :index, - namespace_id: project.namespace, - project_id: project, format: :json, - search: 'master' + params: { + namespace_id: project.namespace, + project_id: project, + search: 'master' + } parsed_response = JSON.parse(response.body) @@ -423,10 +450,12 @@ describe Projects::BranchesController do context 'when cache is enabled yet cold', :request_store do it 'return with a status 200' do get :index, - namespace_id: project.namespace, - project_id: project, - state: 'all', - format: :html + format: :html, + params: { + namespace_id: project.namespace, + project_id: project, + state: 'all' + } expect(response).to have_gitlab_http_status(200) end @@ -439,10 +468,12 @@ describe Projects::BranchesController do it 'return with a status 200' do get :index, - namespace_id: project.namespace, - project_id: project, - state: 'all', - format: :html + format: :html, + params: { + namespace_id: project.namespace, + project_id: project, + state: 'all' + } expect(response).to have_gitlab_http_status(200) end @@ -451,30 +482,36 @@ describe Projects::BranchesController do context 'when deprecated sort/search/page parameters are specified' do it 'returns with a status 301 when sort specified' do get :index, - namespace_id: project.namespace, - project_id: project, - sort: 'updated_asc', - format: :html + format: :html, + params: { + namespace_id: project.namespace, + project_id: project, + sort: 'updated_asc' + } expect(response).to redirect_to project_branches_filtered_path(project, state: 'all') end it 'returns with a status 301 when search specified' do get :index, - namespace_id: project.namespace, - project_id: project, - search: 'feature', - format: :html + format: :html, + params: { + namespace_id: project.namespace, + project_id: project, + search: 'feature' + } expect(response).to redirect_to project_branches_filtered_path(project, state: 'all') end it 'returns with a status 301 when page specified' do get :index, - namespace_id: project.namespace, - project_id: project, - page: 2, - format: :html + format: :html, + params: { + namespace_id: project.namespace, + project_id: project, + page: 2 + } expect(response).to redirect_to project_branches_filtered_path(project, state: 'all') end diff --git a/spec/controllers/projects/ci/lints_controller_spec.rb b/spec/controllers/projects/ci/lints_controller_spec.rb index 1249a5528a9..cfa010c2d1c 100644 --- a/spec/controllers/projects/ci/lints_controller_spec.rb +++ b/spec/controllers/projects/ci/lints_controller_spec.rb @@ -13,7 +13,7 @@ describe Projects::Ci::LintsController do before do project.add_developer(user) - get :show, namespace_id: project.namespace, project_id: project + get :show, params: { namespace_id: project.namespace, project_id: project } end it 'should be success' do @@ -33,7 +33,7 @@ describe Projects::Ci::LintsController do before do project.add_guest(user) - get :show, namespace_id: project.namespace, project_id: project + get :show, params: { namespace_id: project.namespace, project_id: project } end it 'should respond with 404' do @@ -51,7 +51,6 @@ describe Projects::Ci::LintsController do - apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs - ruby -v - which ruby - - gem install bundler --no-ri --no-rdoc - bundle install --jobs $(nproc) "${FLAGS[@]}" HEREDOC end @@ -72,7 +71,7 @@ describe Projects::Ci::LintsController do WebMock.stub_request(:get, remote_file_path).to_return(body: remote_file_content) project.add_developer(user) - post :create, namespace_id: project.namespace, project_id: project, content: content + post :create, params: { namespace_id: project.namespace, project_id: project, content: content } end it 'should be success' do @@ -100,7 +99,7 @@ describe Projects::Ci::LintsController do before do project.add_developer(user) - post :create, namespace_id: project.namespace, project_id: project, content: content + post :create, params: { namespace_id: project.namespace, project_id: project, content: content } end it 'should assign errors' do @@ -112,7 +111,7 @@ describe Projects::Ci::LintsController do before do project.add_guest(user) - post :create, namespace_id: project.namespace, project_id: project, content: content + post :create, params: { namespace_id: project.namespace, project_id: project, content: content } end it 'should respond with 404' do diff --git a/spec/controllers/projects/clusters/applications_controller_spec.rb b/spec/controllers/projects/clusters/applications_controller_spec.rb index 8106453a775..cb558259225 100644 --- a/spec/controllers/projects/clusters/applications_controller_spec.rb +++ b/spec/controllers/projects/clusters/applications_controller_spec.rb @@ -81,7 +81,7 @@ describe Projects::Clusters::ApplicationsController do end def go - post :create, params.merge(namespace_id: project.namespace, project_id: project) + post :create, params: params.merge(namespace_id: project.namespace, project_id: project) end end end diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb index 483222363bb..d94c18ddc02 100644 --- a/spec/controllers/projects/clusters_controller_spec.rb +++ b/spec/controllers/projects/clusters_controller_spec.rb @@ -18,7 +18,7 @@ describe Projects::ClustersController do describe 'GET index' do def go(params = {}) - get :index, params.reverse_merge(namespace_id: project.namespace.to_param, project_id: project) + get :index, params: params.reverse_merge(namespace_id: project.namespace.to_param, project_id: project) end describe 'functionality' do @@ -80,7 +80,7 @@ describe Projects::ClustersController do describe 'GET new' do def go - get :new, namespace_id: project.namespace, project_id: project + get :new, params: { namespace_id: project.namespace, project_id: project } end describe 'functionality for new cluster' do @@ -174,7 +174,7 @@ describe Projects::ClustersController do end def go - post :create_gcp, params.merge(namespace_id: project.namespace, project_id: project) + post :create_gcp, params: params.merge(namespace_id: project.namespace, project_id: project) end describe 'functionality' do @@ -261,7 +261,7 @@ describe Projects::ClustersController do end def go - post :create_user, params.merge(namespace_id: project.namespace, project_id: project) + post :create_user, params: params.merge(namespace_id: project.namespace, project_id: project) end describe 'functionality' do @@ -311,7 +311,7 @@ describe Projects::ClustersController do describe 'security' do before do - allow(ClusterPlatformConfigureWorker).to receive(:perform_async) + allow(ClusterConfigureWorker).to receive(:perform_async) stub_kubeclient_get_namespace('https://kubernetes.example.com', namespace: 'my-namespace') end @@ -331,9 +331,11 @@ describe Projects::ClustersController do def go get :cluster_status, - namespace_id: project.namespace.to_param, - project_id: project.to_param, - id: cluster, + params: { + namespace_id: project.namespace.to_param, + project_id: project.to_param, + id: cluster + }, format: :json end @@ -369,9 +371,11 @@ describe Projects::ClustersController do def go get :show, - namespace_id: project.namespace, - project_id: project, - id: cluster + params: { + namespace_id: project.namespace, + project_id: project, + id: cluster + } end describe 'functionality' do @@ -397,15 +401,15 @@ describe Projects::ClustersController do describe 'PUT update' do def go(format: :html) - put :update, params.merge(namespace_id: project.namespace.to_param, - project_id: project.to_param, - id: cluster, - format: format - ) + put :update, params: params.merge(namespace_id: project.namespace.to_param, + project_id: project.to_param, + id: cluster, + format: format + ) end before do - allow(ClusterPlatformConfigureWorker).to receive(:perform_async) + allow(ClusterConfigureWorker).to receive(:perform_async) stub_kubeclient_get_namespace('https://kubernetes.example.com', namespace: 'my-namespace') end @@ -500,9 +504,11 @@ describe Projects::ClustersController do def go delete :destroy, - namespace_id: project.namespace, - project_id: project, - id: cluster + params: { + namespace_id: project.namespace, + project_id: project, + id: cluster + } end describe 'functionality' do diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb index e34fdee62d6..26eec90da06 100644 --- a/spec/controllers/projects/commit_controller_spec.rb +++ b/spec/controllers/projects/commit_controller_spec.rb @@ -21,7 +21,7 @@ describe Projects::CommitController do project_id: project } - get :show, params.merge(extra_params) + get :show, params: params.merge(extra_params) end context 'with valid id' do @@ -102,9 +102,11 @@ describe Projects::CommitController do it 'renders it' do get(:show, - namespace_id: fork_project.namespace, - project_id: fork_project, - id: commit.id) + params: { + namespace_id: fork_project.namespace, + project_id: fork_project, + id: commit.id + }) expect(response).to be_success end @@ -132,9 +134,11 @@ describe Projects::CommitController do commit = project.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e') get(:branches, - namespace_id: project.namespace, - project_id: project, - id: commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + id: commit.id + }) expect(assigns(:branches)).to include('master', 'feature_conflict') expect(assigns(:branches_limit_exceeded)).to be_falsey @@ -148,9 +152,11 @@ describe Projects::CommitController do allow_any_instance_of(Repository).to receive(:tag_count).and_return(1001) get(:branches, - namespace_id: project.namespace, - project_id: project, - id: commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + id: commit.id + }) expect(assigns(:branches)).to eq([]) expect(assigns(:branches_limit_exceeded)).to be_truthy @@ -163,9 +169,11 @@ describe Projects::CommitController do context 'when target branch is not provided' do it 'renders the 404 page' do post(:revert, - namespace_id: project.namespace, - project_id: project, - id: commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + id: commit.id + }) expect(response).not_to be_success expect(response).to have_gitlab_http_status(404) @@ -175,10 +183,12 @@ describe Projects::CommitController do context 'when the revert was successful' do it 'redirects to the commits page' do post(:revert, - namespace_id: project.namespace, - project_id: project, - start_branch: 'master', - id: commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + start_branch: 'master', + id: commit.id + }) expect(response).to redirect_to project_commits_path(project, 'master') expect(flash[:notice]).to eq('The commit has been successfully reverted.') @@ -188,19 +198,23 @@ describe Projects::CommitController do context 'when the revert failed' do before do post(:revert, - namespace_id: project.namespace, - project_id: project, - start_branch: 'master', - id: commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + start_branch: 'master', + id: commit.id + }) end it 'redirects to the commit page' do # Reverting a commit that has been already reverted. post(:revert, - namespace_id: project.namespace, - project_id: project, - start_branch: 'master', - id: commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + start_branch: 'master', + id: commit.id + }) expect(response).to redirect_to project_commit_path(project, commit.id) expect(flash[:alert]).to match('Sorry, we cannot revert this commit automatically.') @@ -212,9 +226,11 @@ describe Projects::CommitController do context 'when target branch is not provided' do it 'renders the 404 page' do post(:cherry_pick, - namespace_id: project.namespace, - project_id: project, - id: master_pickable_commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + id: master_pickable_commit.id + }) expect(response).not_to be_success expect(response).to have_gitlab_http_status(404) @@ -224,10 +240,12 @@ describe Projects::CommitController do context 'when the cherry-pick was successful' do it 'redirects to the commits page' do post(:cherry_pick, - namespace_id: project.namespace, - project_id: project, - start_branch: 'master', - id: master_pickable_commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + start_branch: 'master', + id: master_pickable_commit.id + }) expect(response).to redirect_to project_commits_path(project, 'master') expect(flash[:notice]).to eq('The commit has been successfully cherry-picked into master.') @@ -237,19 +255,23 @@ describe Projects::CommitController do context 'when the cherry_pick failed' do before do post(:cherry_pick, - namespace_id: project.namespace, - project_id: project, - start_branch: 'master', - id: master_pickable_commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + start_branch: 'master', + id: master_pickable_commit.id + }) end it 'redirects to the commit page' do # Cherry-picking a commit that has been already cherry-picked. post(:cherry_pick, - namespace_id: project.namespace, - project_id: project, - start_branch: 'master', - id: master_pickable_commit.id) + params: { + namespace_id: project.namespace, + project_id: project, + start_branch: 'master', + id: master_pickable_commit.id + }) expect(response).to redirect_to project_commit_path(project, master_pickable_commit.id) expect(flash[:alert]).to match('Sorry, we cannot cherry-pick this commit automatically.') @@ -264,7 +286,7 @@ describe Projects::CommitController do project_id: project } - get :diff_for_path, params.merge(extra_params) + get :diff_for_path, params: params.merge(extra_params) end let(:existing_path) { '.gitmodules' } @@ -332,7 +354,7 @@ describe Projects::CommitController do project_id: project } - get :pipelines, params.merge(extra_params) + get :pipelines, params: params.merge(extra_params) end context 'when the commit exists' do diff --git a/spec/controllers/projects/commits_controller_spec.rb b/spec/controllers/projects/commits_controller_spec.rb index 80513650636..8cb9130b834 100644 --- a/spec/controllers/projects/commits_controller_spec.rb +++ b/spec/controllers/projects/commits_controller_spec.rb @@ -17,8 +17,10 @@ describe Projects::CommitsController do context "no ref is provided" do it 'should redirect to the default branch of the project' do get(:commits_root, - namespace_id: project.namespace, - project_id: project) + params: { + namespace_id: project.namespace, + project_id: project + }) expect(response).to redirect_to project_commits_path(project) end @@ -31,9 +33,11 @@ describe Projects::CommitsController do context 'with file path' do before do get(:show, - namespace_id: project.namespace, - project_id: project, - id: id) + params: { + namespace_id: project.namespace, + project_id: project, + id: id + }) end context "valid branch, valid file" do @@ -65,9 +69,11 @@ describe Projects::CommitsController do context "when the ref does not exist with the suffix" do before do get(:show, - namespace_id: project.namespace, - project_id: project, - id: "master.atom") + params: { + namespace_id: project.namespace, + project_id: project, + id: "master.atom" + }) end it "renders as atom" do @@ -88,9 +94,11 @@ describe Projects::CommitsController do allow_any_instance_of(Repository).to receive(:commit).with('master.atom').and_return(commit) get(:show, - namespace_id: project.namespace, - project_id: project, - id: "master.atom") + params: { + namespace_id: project.namespace, + project_id: project, + id: "master.atom" + }) end it "renders as HTML" do @@ -106,9 +114,11 @@ describe Projects::CommitsController do before do get(:signatures, - namespace_id: project.namespace, - project_id: project, - id: id, + params: { + namespace_id: project.namespace, + project_id: project, + id: id + }, format: :json) end diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb index 17883d0fadd..cfd70e93efb 100644 --- a/spec/controllers/projects/compare_controller_spec.rb +++ b/spec/controllers/projects/compare_controller_spec.rb @@ -13,7 +13,7 @@ describe Projects::CompareController do render_views before do - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } end it 'returns successfully' do @@ -24,7 +24,7 @@ describe Projects::CompareController do describe 'GET show' do render_views - subject(:show_request) { get :show, request_params } + subject(:show_request) { get :show, params: request_params } let(:request_params) do { @@ -130,7 +130,7 @@ describe Projects::CompareController do project_id: project } - get :diff_for_path, params.merge(extra_params) + get :diff_for_path, params: params.merge(extra_params) end let(:existing_path) { 'files/ruby/feature.rb' } @@ -201,7 +201,7 @@ describe Projects::CompareController do end describe 'POST create' do - subject(:create_request) { post :create, request_params } + subject(:create_request) { post :create, params: request_params } let(:request_params) do { @@ -260,7 +260,7 @@ describe Projects::CompareController do end describe 'GET signatures' do - subject(:signatures_request) { get :signatures, request_params } + subject(:signatures_request) { get :signatures, params: request_params } let(:request_params) do { diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb index 5c79269e8f1..6a63cbdf8e2 100644 --- a/spec/controllers/projects/cycle_analytics_controller_spec.rb +++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb @@ -13,8 +13,10 @@ describe Projects::CycleAnalyticsController do context 'with no data' do it 'is true' do get(:show, - namespace_id: project.namespace, - project_id: project) + params: { + namespace_id: project.namespace, + project_id: project + }) expect(response).to be_success expect(assigns(:cycle_analytics_no_data)).to eq(true) @@ -32,8 +34,10 @@ describe Projects::CycleAnalyticsController do it 'is false' do get(:show, - namespace_id: project.namespace, - project_id: project) + params: { + namespace_id: project.namespace, + project_id: project + }) expect(response).to be_success expect(assigns(:cycle_analytics_no_data)).to eq(false) diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb index 4567a51b88e..e54cf3e8181 100644 --- a/spec/controllers/projects/deploy_keys_controller_spec.rb +++ b/spec/controllers/projects/deploy_keys_controller_spec.rb @@ -16,8 +16,8 @@ describe Projects::DeployKeysController do end context 'when html requested' do - it 'redirects to blob' do - get :index, params + it 'redirects to project settings with the correct anchor' do + get :index, params: params expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings')) end @@ -48,7 +48,7 @@ describe Projects::DeployKeysController do end it 'returns json in a correct format' do - get :index, params.merge(format: :json) + get :index, params: params.merge(format: :json) json = JSON.parse(response.body) @@ -60,6 +60,40 @@ describe Projects::DeployKeysController do end end + describe 'POST create' do + def create_params(title = 'my-key') + { + namespace_id: project.namespace.path, + project_id: project.path, + deploy_key: { + title: title, + key: attributes_for(:deploy_key)[:key], + deploy_keys_projects_attributes: { '0' => { can_push: '1' } } + } + } + end + + it 'creates a new deploy key for the project' do + expect { post :create, params: create_params }.to change(project.deploy_keys, :count).by(1) + + expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings')) + end + + it 'redirects to project settings with the correct anchor' do + post :create, params: create_params + + expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings')) + end + + context 'when the deploy key is invalid' do + it 'shows an alert with the validations errors' do + post :create, params: create_params(nil) + + expect(flash[:alert]).to eq("Title can't be blank, Deploy keys projects deploy key title can't be blank") + end + end + end + describe '/enable/:id' do let(:deploy_key) { create(:deploy_key) } let(:project2) { create(:project) } @@ -74,7 +108,7 @@ describe Projects::DeployKeysController do it 'redirects to login' do expect do - put :enable, id: deploy_key.id, namespace_id: project.namespace, project_id: project + put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project } end.not_to change { DeployKeysProject.count } expect(response).to have_http_status(302) @@ -89,7 +123,7 @@ describe Projects::DeployKeysController do it 'returns 404' do expect do - put :enable, id: deploy_key.id, namespace_id: project.namespace, project_id: project + put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project } end.not_to change { DeployKeysProject.count } expect(response).to have_http_status(404) @@ -103,7 +137,7 @@ describe Projects::DeployKeysController do it 'returns 302' do expect do - put :enable, id: deploy_key.id, namespace_id: project.namespace, project_id: project + put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project } end.to change { DeployKeysProject.count }.by(1) expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1) @@ -112,7 +146,7 @@ describe Projects::DeployKeysController do end it 'returns 404' do - put :enable, id: 0, namespace_id: project.namespace, project_id: project + put :enable, params: { id: 0, namespace_id: project.namespace, project_id: project } expect(response).to have_http_status(404) end @@ -125,7 +159,7 @@ describe Projects::DeployKeysController do it 'returns 302' do expect do - put :enable, id: deploy_key.id, namespace_id: project.namespace, project_id: project + put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project } end.to change { DeployKeysProject.count }.by(1) expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1) @@ -145,7 +179,7 @@ describe Projects::DeployKeysController do end it 'redirects to login' do - put :disable, id: deploy_key.id, namespace_id: project.namespace, project_id: project + put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project } expect(response).to have_http_status(302) expect(response).to redirect_to(new_user_session_path) @@ -159,7 +193,7 @@ describe Projects::DeployKeysController do end it 'returns 404' do - put :disable, id: deploy_key.id, namespace_id: project.namespace, project_id: project + put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project } expect(response).to have_http_status(404) expect(DeployKey.find(deploy_key.id)).to eq(deploy_key) @@ -168,7 +202,7 @@ describe Projects::DeployKeysController do context 'with user with permission' do it 'returns 302' do - put :disable, id: deploy_key.id, namespace_id: project.namespace, project_id: project + put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project } expect(response).to have_http_status(302) expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings')) @@ -177,7 +211,7 @@ describe Projects::DeployKeysController do end it 'returns 404' do - put :disable, id: 0, namespace_id: project.namespace, project_id: project + put :disable, params: { id: 0, namespace_id: project.namespace, project_id: project } expect(response).to have_http_status(404) end @@ -190,7 +224,7 @@ describe Projects::DeployKeysController do it 'returns 302' do expect do - put :disable, id: deploy_key.id, namespace_id: project.namespace, project_id: project + put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project } end.to change { DeployKey.count }.by(-1) expect(response).to have_http_status(302) diff --git a/spec/controllers/projects/deployments_controller_spec.rb b/spec/controllers/projects/deployments_controller_spec.rb index 5b7da81b6a1..5c33098fd31 100644 --- a/spec/controllers/projects/deployments_controller_spec.rb +++ b/spec/controllers/projects/deployments_controller_spec.rb @@ -19,7 +19,7 @@ describe Projects::DeploymentsController do create(:deployment, :success, environment: environment, created_at: 7.hours.ago) create(:deployment, :success, environment: environment) - get :index, deployment_params(after: 8.hours.ago) + get :index, params: deployment_params(after: 8.hours.ago) expect(response).to be_ok @@ -29,7 +29,7 @@ describe Projects::DeploymentsController do it 'returns a list with deployments information' do create(:deployment, :success, environment: environment) - get :index, deployment_params + get :index, params: deployment_params expect(response).to be_ok expect(response).to match_response_schema('deployments') @@ -49,7 +49,7 @@ describe Projects::DeploymentsController do end it 'responds with not found' do - get :metrics, deployment_params(id: deployment.id) + get :metrics, params: deployment_params(id: deployment.id) expect(response).to be_not_found end @@ -66,7 +66,7 @@ describe Projects::DeploymentsController do end it 'returns a empty response 204 resposne' do - get :metrics, deployment_params(id: deployment.id) + get :metrics, params: deployment_params(id: deployment.id) expect(response).to have_gitlab_http_status(204) expect(response.body).to eq('') end @@ -86,7 +86,7 @@ describe Projects::DeploymentsController do end it 'returns a metrics JSON document' do - get :metrics, deployment_params(id: deployment.id) + get :metrics, params: deployment_params(id: deployment.id) expect(response).to be_ok expect(json_response['success']).to be(true) @@ -101,7 +101,7 @@ describe Projects::DeploymentsController do end it 'responds with not found' do - get :metrics, deployment_params(id: deployment.id) + get :metrics, params: deployment_params(id: deployment.id) expect(response).to be_not_found end @@ -122,7 +122,7 @@ describe Projects::DeploymentsController do end it 'responds with not found' do - get :metrics, deployment_params(id: deployment.id) + get :metrics, params: deployment_params(id: deployment.id) expect(response).to be_not_found end @@ -141,7 +141,7 @@ describe Projects::DeploymentsController do end it 'returns a empty response 204 response' do - get :additional_metrics, deployment_params(id: deployment.id, format: :json) + get :additional_metrics, params: deployment_params(id: deployment.id, format: :json) expect(response).to have_gitlab_http_status(204) expect(response.body).to eq('') end @@ -161,7 +161,7 @@ describe Projects::DeploymentsController do end it 'returns a metrics JSON document' do - get :additional_metrics, deployment_params(id: deployment.id, format: :json) + get :additional_metrics, params: deployment_params(id: deployment.id, format: :json) expect(response).to be_ok expect(json_response['success']).to be(true) diff --git a/spec/controllers/projects/discussions_controller_spec.rb b/spec/controllers/projects/discussions_controller_spec.rb index 4aa33dbbb01..0b9f336cf13 100644 --- a/spec/controllers/projects/discussions_controller_spec.rb +++ b/spec/controllers/projects/discussions_controller_spec.rb @@ -23,7 +23,7 @@ describe Projects::DiscussionsController do context 'when user is not authorized to read the MR' do it 'returns 404' do - get :show, request_params, format: :json + get :show, params: request_params, session: { format: :json } expect(response).to have_gitlab_http_status(404) end @@ -35,7 +35,7 @@ describe Projects::DiscussionsController do end it 'returns status 200' do - get :show, request_params, format: :json + get :show, params: request_params, session: { format: :json } expect(response).to have_gitlab_http_status(200) end @@ -43,7 +43,7 @@ describe Projects::DiscussionsController do it 'returns status 404 if MR does not exists' do merge_request.destroy! - get :show, request_params, format: :json + get :show, params: request_params, session: { format: :json } expect(response).to have_gitlab_http_status(404) end @@ -56,7 +56,7 @@ describe Projects::DiscussionsController do end it 'returns status 200' do - get :show, request_params, format: :json + get :show, params: request_params, session: { format: :json } expect(response).to have_gitlab_http_status(200) end @@ -70,7 +70,7 @@ describe Projects::DiscussionsController do context "when the user is not authorized to resolve the discussion" do it "returns status 404" do - post :resolve, request_params + post :resolve, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -87,7 +87,7 @@ describe Projects::DiscussionsController do end it "returns status 404" do - post :resolve, request_params + post :resolve, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -95,7 +95,7 @@ describe Projects::DiscussionsController do context "when the discussion is resolvable" do it "resolves the discussion" do - post :resolve, request_params + post :resolve, params: request_params expect(note.reload.discussion.resolved?).to be true expect(note.reload.discussion.resolved_by).to eq(user) @@ -104,17 +104,17 @@ describe Projects::DiscussionsController do it "sends notifications if all discussions are resolved" do expect_any_instance_of(MergeRequests::ResolvedDiscussionNotificationService).to receive(:execute).with(merge_request) - post :resolve, request_params + post :resolve, params: request_params end it "returns the name of the resolving user" do - post :resolve, request_params + post :resolve, params: request_params expect(JSON.parse(response.body)['resolved_by']['name']).to eq(user.name) end it "returns status 200" do - post :resolve, request_params + post :resolve, params: request_params expect(response).to have_gitlab_http_status(200) end @@ -123,7 +123,7 @@ describe Projects::DiscussionsController do expect_any_instance_of(DiscussionSerializer).to receive(:represent) .with(instance_of(Discussion), { context: instance_of(described_class), render_truncated_diff_lines: true }) - post :resolve, request_params + post :resolve, params: request_params end context 'diff discussion' do @@ -131,7 +131,7 @@ describe Projects::DiscussionsController do let(:discussion) { note.discussion } it "returns truncated diff lines" do - post :resolve, request_params + post :resolve, params: request_params expect(JSON.parse(response.body)['truncated_diff_lines']).to be_present end @@ -149,7 +149,7 @@ describe Projects::DiscussionsController do context "when the user is not authorized to resolve the discussion" do it "returns status 404" do - delete :unresolve, request_params + delete :unresolve, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -166,7 +166,7 @@ describe Projects::DiscussionsController do end it "returns status 404" do - delete :unresolve, request_params + delete :unresolve, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -174,13 +174,13 @@ describe Projects::DiscussionsController do context "when the discussion is resolvable" do it "unresolves the discussion" do - delete :unresolve, request_params + delete :unresolve, params: request_params expect(note.reload.discussion.resolved?).to be false end it "returns status 200" do - delete :unresolve, request_params + delete :unresolve, params: request_params expect(response).to have_gitlab_http_status(200) end @@ -194,7 +194,7 @@ describe Projects::DiscussionsController do expect_any_instance_of(DiscussionSerializer).to receive(:represent) .with(instance_of(Discussion), { context: instance_of(described_class), render_truncated_diff_lines: true }) - delete :unresolve, request_params + delete :unresolve, params: request_params end end end diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 5fa0488014f..94fb85f217c 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -17,7 +17,7 @@ describe Projects::EnvironmentsController do describe 'GET index' do context 'when a request for the HTML is made' do it 'responds with status code 200' do - get :index, environment_params + get :index, params: environment_params expect(response).to have_gitlab_http_status(:ok) end @@ -26,7 +26,7 @@ describe Projects::EnvironmentsController do expect_any_instance_of(Gitlab::EtagCaching::Store) .to receive(:touch).with(project_environments_path(project, format: :json)) - get :index, environment_params + get :index, params: environment_params end end @@ -49,7 +49,7 @@ describe Projects::EnvironmentsController do context 'when requesting available environments scope' do before do - get :index, environment_params(format: :json, scope: :available) + get :index, params: environment_params(format: :json, scope: :available) end it 'responds with a payload describing available environments' do @@ -73,7 +73,7 @@ describe Projects::EnvironmentsController do context 'when requesting stopped environments scope' do before do - get :index, environment_params(format: :json, scope: :stopped) + get :index, params: environment_params(format: :json, scope: :stopped) end it 'responds with a payload describing stopped environments' do @@ -103,9 +103,11 @@ describe Projects::EnvironmentsController do context 'when using default format' do it 'responds with HTML' do - get :folder, namespace_id: project.namespace, - project_id: project, - id: 'staging-1.0' + get :folder, params: { + namespace_id: project.namespace, + project_id: project, + id: 'staging-1.0' + } expect(response).to be_ok expect(response).to render_template 'folder' @@ -114,9 +116,11 @@ describe Projects::EnvironmentsController do context 'when using JSON format' do it 'sorts the subfolders lexicographically' do - get :folder, namespace_id: project.namespace, - project_id: project, - id: 'staging-1.0', + get :folder, params: { + namespace_id: project.namespace, + project_id: project, + id: 'staging-1.0' + }, format: :json expect(response).to be_ok @@ -132,7 +136,7 @@ describe Projects::EnvironmentsController do describe 'GET show' do context 'with valid id' do it 'responds with a status code 200' do - get :show, environment_params + get :show, params: environment_params expect(response).to be_ok end @@ -142,7 +146,7 @@ describe Projects::EnvironmentsController do it 'responds with a status code 404' do params = environment_params params[:id] = 12345 - get :show, params + get :show, params: params expect(response).to have_gitlab_http_status(404) end @@ -151,7 +155,7 @@ describe Projects::EnvironmentsController do describe 'GET edit' do it 'responds with a status code 200' do - get :edit, environment_params + get :edit, params: environment_params expect(response).to be_ok end @@ -160,7 +164,7 @@ describe Projects::EnvironmentsController do describe 'PATCH #update' do it 'responds with a 302' do patch_params = environment_params.merge(environment: { external_url: 'https://git.gitlab.com' }) - patch :update, patch_params + patch :update, params: patch_params expect(response).to have_gitlab_http_status(302) end @@ -171,7 +175,7 @@ describe Projects::EnvironmentsController do it 'returns 404' do allow_any_instance_of(Environment).to receive(:available?) { false } - patch :stop, environment_params(format: :json) + patch :stop, params: environment_params(format: :json) expect(response).to have_gitlab_http_status(404) end @@ -184,7 +188,7 @@ describe Projects::EnvironmentsController do allow_any_instance_of(Environment) .to receive_messages(available?: true, stop_with_action!: action) - patch :stop, environment_params(format: :json) + patch :stop, params: environment_params(format: :json) expect(response).to have_gitlab_http_status(200) expect(json_response).to eq( @@ -198,7 +202,7 @@ describe Projects::EnvironmentsController do allow_any_instance_of(Environment) .to receive_messages(available?: true, stop_with_action!: nil) - patch :stop, environment_params(format: :json) + patch :stop, params: environment_params(format: :json) expect(response).to have_gitlab_http_status(200) expect(json_response).to eq( @@ -211,7 +215,7 @@ describe Projects::EnvironmentsController do describe 'GET #terminal' do context 'with valid id' do it 'responds with a status code 200' do - get :terminal, environment_params + get :terminal, params: environment_params expect(response).to have_gitlab_http_status(200) end @@ -222,13 +226,13 @@ describe Projects::EnvironmentsController do expect_any_instance_of(defined?(EE) ? EE::Environment : Environment) .to receive(:terminals) - get :terminal, environment_params + get :terminal, params: environment_params end end context 'with invalid id' do it 'responds with a status code 404' do - get :terminal, environment_params(id: 666) + get :terminal, params: environment_params(id: 666) expect(response).to have_gitlab_http_status(404) end @@ -254,7 +258,7 @@ describe Projects::EnvironmentsController do .with(:fake_terminal) .and_return(workhorse: :response) - get :terminal_websocket_authorize, environment_params + get :terminal_websocket_authorize, params: environment_params expect(response).to have_gitlab_http_status(200) expect(response.headers["Content-Type"]).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) @@ -264,7 +268,7 @@ describe Projects::EnvironmentsController do context 'and invalid id' do it 'returns 404' do - get :terminal_websocket_authorize, environment_params(id: 666) + get :terminal_websocket_authorize, params: environment_params(id: 666) expect(response).to have_gitlab_http_status(404) end @@ -275,7 +279,7 @@ describe Projects::EnvironmentsController do it 'aborts with an exception' do allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_raise(JWT::DecodeError) - expect { get :terminal_websocket_authorize, environment_params }.to raise_error(JWT::DecodeError) + expect { get :terminal_websocket_authorize, params: environment_params }.to raise_error(JWT::DecodeError) # controller tests don't set the response status correctly. It's enough # to check that the action raised an exception end @@ -288,13 +292,13 @@ describe Projects::EnvironmentsController do it 'redirects to environment if it exists' do environment = create(:environment, name: 'production', project: project) - get :metrics_redirect, namespace_id: project.namespace, project_id: project + get :metrics_redirect, params: { namespace_id: project.namespace, project_id: project } expect(response).to redirect_to(environment_metrics_path(environment)) end it 'redirects to empty page if no environment exists' do - get :metrics_redirect, namespace_id: project.namespace, project_id: project + get :metrics_redirect, params: { namespace_id: project.namespace, project_id: project } expect(response).to be_ok expect(response).to render_template 'empty' @@ -312,14 +316,14 @@ describe Projects::EnvironmentsController do end it 'returns a metrics page' do - get :metrics, environment_params + get :metrics, params: environment_params expect(response).to be_ok end context 'when requesting metrics as JSON' do it 'returns a metrics JSON document' do - get :metrics, environment_params(format: :json) + get :metrics, params: environment_params(format: :json) expect(response).to have_gitlab_http_status(204) expect(json_response).to eq({}) @@ -337,7 +341,7 @@ describe Projects::EnvironmentsController do end it 'returns a metrics JSON document' do - get :metrics, environment_params(format: :json) + get :metrics, params: environment_params(format: :json) expect(response).to be_ok expect(json_response['success']).to be(true) @@ -359,7 +363,7 @@ describe Projects::EnvironmentsController do context 'when requesting metrics as JSON' do it 'returns a metrics JSON document' do - get :additional_metrics, environment_params(format: :json) + get :additional_metrics, params: environment_params(format: :json) expect(response).to have_gitlab_http_status(204) expect(json_response).to eq({}) @@ -379,7 +383,7 @@ describe Projects::EnvironmentsController do end it 'returns a metrics JSON document' do - get :additional_metrics, environment_params(format: :json) + get :additional_metrics, params: environment_params(format: :json) expect(response).to be_ok expect(json_response['success']).to be(true) diff --git a/spec/controllers/projects/find_file_controller_spec.rb b/spec/controllers/projects/find_file_controller_spec.rb index 66fe41108e2..9072d67af07 100644 --- a/spec/controllers/projects/find_file_controller_spec.rb +++ b/spec/controllers/projects/find_file_controller_spec.rb @@ -17,9 +17,11 @@ describe Projects::FindFileController do before do get(:show, - namespace_id: project.namespace, - project_id: project, - id: id) + params: { + namespace_id: project.namespace, + project_id: project, + id: id + }) end context "valid branch" do @@ -36,9 +38,11 @@ describe Projects::FindFileController do describe "GET #list" do def go(format: 'json') get :list, - namespace_id: project.namespace, - project_id: project, - id: id, + params: { + namespace_id: project.namespace, + project_id: project, + id: id + }, format: format end diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb index 945b6142abf..0e1663c8585 100644 --- a/spec/controllers/projects/forks_controller_spec.rb +++ b/spec/controllers/projects/forks_controller_spec.rb @@ -13,8 +13,10 @@ describe Projects::ForksController do describe 'GET index' do def get_forks get :index, - namespace_id: project.namespace, - project_id: project + params: { + namespace_id: project.namespace, + project_id: project + } end context 'when fork is public' do @@ -83,8 +85,10 @@ describe Projects::ForksController do describe 'GET new' do def get_new get :new, - namespace_id: project.namespace, - project_id: project + params: { + namespace_id: project.namespace, + project_id: project + } end context 'when user is signed in' do @@ -111,9 +115,11 @@ describe Projects::ForksController do describe 'POST create' do def post_create post :create, - namespace_id: project.namespace, - project_id: project, - namespace_key: user.namespace.id + params: { + namespace_id: project.namespace, + project_id: project, + namespace_key: user.namespace.id + } end context 'when user is signed in' do diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb index da78592a6f6..73fb7307e11 100644 --- a/spec/controllers/projects/graphs_controller_spec.rb +++ b/spec/controllers/projects/graphs_controller_spec.rb @@ -11,7 +11,7 @@ describe Projects::GraphsController do describe 'GET languages' do it "redirects_to action charts" do - get(:commits, namespace_id: project.namespace.path, project_id: project.path, id: 'master') + get(:commits, params: { namespace_id: project.namespace.path, project_id: project.path, id: 'master' }) expect(response).to redirect_to action: :charts end @@ -19,7 +19,7 @@ describe Projects::GraphsController do describe 'GET commits' do it "redirects_to action charts" do - get(:commits, namespace_id: project.namespace.path, project_id: project.path, id: 'master') + get(:commits, params: { namespace_id: project.namespace.path, project_id: project.path, id: 'master' }) expect(response).to redirect_to action: :charts end diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb index 879aff26deb..675eeff8d12 100644 --- a/spec/controllers/projects/group_links_controller_spec.rb +++ b/spec/controllers/projects/group_links_controller_spec.rb @@ -14,10 +14,12 @@ describe Projects::GroupLinksController do describe '#create' do shared_context 'link project to group' do before do - post(:create, namespace_id: project.namespace, - project_id: project, - link_group_id: group.id, - link_group_access: ProjectGroupLink.default_access) + post(:create, params: { + namespace_id: project.namespace, + project_id: project, + link_group_id: group.id, + link_group_access: ProjectGroupLink.default_access + }) end end @@ -65,10 +67,12 @@ describe Projects::GroupLinksController do context 'when project group id equal link group id' do before do - post(:create, namespace_id: project.namespace, - project_id: project, - link_group_id: group2.id, - link_group_access: ProjectGroupLink.default_access) + post(:create, params: { + namespace_id: project.namespace, + project_id: project, + link_group_id: group2.id, + link_group_access: ProjectGroupLink.default_access + }) end it 'does not share project with selected group' do @@ -84,9 +88,11 @@ describe Projects::GroupLinksController do context 'when link group id is not present' do before do - post(:create, namespace_id: project.namespace, - project_id: project, - link_group_access: ProjectGroupLink.default_access) + post(:create, params: { + namespace_id: project.namespace, + project_id: project, + link_group_access: ProjectGroupLink.default_access + }) end it 'redirects to project group links page' do diff --git a/spec/controllers/projects/hooks_controller_spec.rb b/spec/controllers/projects/hooks_controller_spec.rb index 7d3a8c3d0d3..3037c922b68 100644 --- a/spec/controllers/projects/hooks_controller_spec.rb +++ b/spec/controllers/projects/hooks_controller_spec.rb @@ -11,7 +11,7 @@ describe Projects::HooksController do describe '#index' do it 'redirects to settings/integrations page' do - get(:index, namespace_id: project.namespace, project_id: project) + get(:index, params: { namespace_id: project.namespace, project_id: project }) expect(response).to redirect_to( project_settings_integrations_path(project) @@ -38,7 +38,7 @@ describe Projects::HooksController do wiki_page_events: true } - post :create, namespace_id: project.namespace, project_id: project, hook: hook_params + post :create, params: { namespace_id: project.namespace, project_id: project, hook: hook_params } expect(response).to have_http_status(302) expect(ProjectHook.all.size).to eq(1) diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb index cdc63f5aab3..3ebfe4b0918 100644 --- a/spec/controllers/projects/imports_controller_spec.rb +++ b/spec/controllers/projects/imports_controller_spec.rb @@ -12,13 +12,13 @@ describe Projects::ImportsController do describe 'GET #show' do context 'when repository does not exists' do it 'renders template' do - get :show, namespace_id: project.namespace.to_param, project_id: project + get :show, params: { namespace_id: project.namespace.to_param, project_id: project } expect(response).to render_template :show end it 'sets flash.now if params is present' do - get :show, namespace_id: project.namespace.to_param, project_id: project, continue: { to: '/', notice_now: 'Started' } + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, continue: { to: '/', notice_now: 'Started' } } expect(flash.now[:notice]).to eq 'Started' end @@ -34,13 +34,13 @@ describe Projects::ImportsController do end it 'renders template' do - get :show, namespace_id: project.namespace.to_param, project_id: project + get :show, params: { namespace_id: project.namespace.to_param, project_id: project } expect(response).to render_template :show end it 'sets flash.now if params is present' do - get :show, namespace_id: project.namespace.to_param, project_id: project, continue: { to: '/', notice_now: 'In progress' } + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, continue: { to: '/', notice_now: 'In progress' } } expect(flash.now[:notice]).to eq 'In progress' end @@ -52,7 +52,7 @@ describe Projects::ImportsController do end it 'redirects to new_namespace_project_import_path' do - get :show, namespace_id: project.namespace.to_param, project_id: project + get :show, params: { namespace_id: project.namespace.to_param, project_id: project } expect(response).to redirect_to new_project_import_path(project) end @@ -67,7 +67,7 @@ describe Projects::ImportsController do it 'redirects to namespace_project_path' do allow_any_instance_of(Project).to receive(:forked?).and_return(true) - get :show, namespace_id: project.namespace.to_param, project_id: project + get :show, params: { namespace_id: project.namespace.to_param, project_id: project } expect(flash[:notice]).to eq 'The project was successfully forked.' expect(response).to redirect_to project_path(project) @@ -76,7 +76,7 @@ describe Projects::ImportsController do context 'when project is external' do it 'redirects to namespace_project_path' do - get :show, namespace_id: project.namespace.to_param, project_id: project + get :show, params: { namespace_id: project.namespace.to_param, project_id: project } expect(flash[:notice]).to eq 'The project was successfully imported.' expect(response).to redirect_to project_path(project) @@ -92,7 +92,7 @@ describe Projects::ImportsController do end it 'redirects to internal params[:to]' do - get :show, namespace_id: project.namespace.to_param, project_id: project, continue: params + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, continue: params } expect(flash[:notice]).to eq params[:notice] expect(response).to redirect_to params[:to] @@ -101,7 +101,7 @@ describe Projects::ImportsController do it 'does not redirect to external params[:to]' do params[:to] = "//google.com" - get :show, namespace_id: project.namespace.to_param, project_id: project, continue: params + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, continue: params } expect(response).not_to redirect_to params[:to] end end @@ -113,7 +113,7 @@ describe Projects::ImportsController do end it 'redirects to namespace_project_path' do - get :show, namespace_id: project.namespace.to_param, project_id: project + get :show, params: { namespace_id: project.namespace.to_param, project_id: project } expect(response).to redirect_to project_path(project) end diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 02930edbf72..a239ac16c0d 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -18,7 +18,7 @@ describe Projects::IssuesController do project.issues_enabled = false project.save! - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(404) end @@ -26,7 +26,7 @@ describe Projects::IssuesController do context 'when GitLab issues enabled' do it 'renders the "index" template' do - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:index) @@ -42,14 +42,16 @@ describe Projects::IssuesController do it_behaves_like "issuables list meta-data", :issue + it_behaves_like 'set sort order from user preference' + it "returns index" do - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(200) end it "returns 301 if request path doesn't match project path" do - get :index, namespace_id: project.namespace, project_id: project.path.upcase + get :index, params: { namespace_id: project.namespace, project_id: project.path.upcase } expect(response).to redirect_to(project_issues_path(project)) end @@ -58,7 +60,7 @@ describe Projects::IssuesController do project.issues_enabled = false project.save! - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(404) end end @@ -75,18 +77,22 @@ describe Projects::IssuesController do it 'redirects to last_page if page number is larger than number of pages' do get :index, - namespace_id: project.namespace.to_param, - project_id: project, - page: (last_page + 1).to_param + params: { + namespace_id: project.namespace.to_param, + project_id: project, + page: (last_page + 1).to_param + } expect(response).to redirect_to(namespace_project_issues_path(page: last_page, state: controller.params[:state], scope: controller.params[:scope])) end it 'redirects to specified page' do get :index, - namespace_id: project.namespace.to_param, - project_id: project, - page: last_page.to_param + params: { + namespace_id: project.namespace.to_param, + project_id: project, + page: last_page.to_param + } expect(assigns(:issues).current_page).to eq(last_page) expect(response).to have_gitlab_http_status(200) @@ -95,10 +101,12 @@ describe Projects::IssuesController do it 'does not redirect to external sites when provided a host field' do external_host = "www.example.com" get :index, - namespace_id: project.namespace.to_param, - project_id: project, - page: (last_page + 1).to_param, - host: external_host + params: { + namespace_id: project.namespace.to_param, + project_id: project, + page: (last_page + 1).to_param, + host: external_host + } expect(response).to redirect_to(namespace_project_issues_path(page: last_page, state: controller.params[:state], scope: controller.params[:scope])) end @@ -107,9 +115,11 @@ describe Projects::IssuesController do allow(controller).to receive(:pagination_disabled?).and_return(true) get :index, - namespace_id: project.namespace.to_param, - project_id: project, - page: (last_page + 1).to_param + params: { + namespace_id: project.namespace.to_param, + project_id: project, + page: (last_page + 1).to_param + } expect(response).to have_gitlab_http_status(200) expect(assigns(:issues).size).to eq(2) @@ -119,7 +129,7 @@ describe Projects::IssuesController do describe 'GET #new' do it 'redirects to signin if not logged in' do - get :new, namespace_id: project.namespace, project_id: project + get :new, params: { namespace_id: project.namespace, project_id: project } expect(flash[:notice]).to eq 'Please sign in to create the new issue.' expect(response).to redirect_to(new_user_session_path) @@ -132,7 +142,7 @@ describe Projects::IssuesController do end it 'builds a new issue' do - get :new, namespace_id: project.namespace, project_id: project + get :new, params: { namespace_id: project.namespace, project_id: project } expect(assigns(:issue)).to be_a_new(Issue) end @@ -142,7 +152,7 @@ describe Projects::IssuesController do project_with_repository.add_developer(user) mr = create(:merge_request_with_diff_notes, source_project: project_with_repository) - get :new, namespace_id: project_with_repository.namespace, project_id: project_with_repository, merge_request_to_resolve_discussions_of: mr.iid + get :new, params: { namespace_id: project_with_repository.namespace, project_id: project_with_repository, merge_request_to_resolve_discussions_of: mr.iid } expect(assigns(:issue).title).not_to be_empty expect(assigns(:issue).description).not_to be_empty @@ -151,7 +161,7 @@ describe Projects::IssuesController do it 'fills in an issue for a discussion' do note = create(:note_on_merge_request, project: project) - get :new, namespace_id: project.namespace.path, project_id: project, merge_request_to_resolve_discussions_of: note.noteable.iid, discussion_to_resolve: note.discussion_id + get :new, params: { namespace_id: project.namespace.path, project_id: project, merge_request_to_resolve_discussions_of: note.noteable.iid, discussion_to_resolve: note.discussion_id } expect(assigns(:issue).title).not_to be_empty expect(assigns(:issue).description).not_to be_empty @@ -176,7 +186,7 @@ describe Projects::IssuesController do project.issues_enabled = false project.save! - get :new, namespace_id: project.namespace, project_id: project + get :new, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(404) end @@ -184,7 +194,7 @@ describe Projects::IssuesController do context 'when GitLab issues enabled' do it 'renders the "new" template' do - get :new, namespace_id: project.namespace, project_id: project + get :new, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:new) @@ -196,12 +206,12 @@ describe Projects::IssuesController do describe 'Redirect after sign in' do context 'with an AJAX request' do it 'does not store the visited URL' do - xhr :get, - :show, + get :show, params: { format: :json, namespace_id: project.namespace, project_id: project, id: issue.iid + }, xhr: true expect(session['user_return_to']).to be_blank end @@ -210,9 +220,11 @@ describe Projects::IssuesController do context 'without an AJAX request' do it 'stores the visited URL' do get :show, - namespace_id: project.namespace.to_param, - project_id: project, - id: issue.iid + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: issue.iid + } expect(session['user_return_to']).to eq("/#{project.namespace.to_param}/#{project.to_param}/issues/#{issue.iid}") end @@ -251,11 +263,13 @@ describe Projects::IssuesController do def move_issue post :move, - format: :json, - namespace_id: project.namespace.to_param, - project_id: project, - id: issue.iid, - move_to_project_id: another_project.id + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: issue.iid, + move_to_project_id: another_project.id + }, + format: :json end end end @@ -263,10 +277,13 @@ describe Projects::IssuesController do describe 'PUT #update' do subject do put :update, - namespace_id: project.namespace, - project_id: project, - id: issue.to_param, - issue: { title: 'New title' }, format: :json + params: { + namespace_id: project.namespace, + project_id: project, + id: issue.to_param, + issue: { title: 'New title' } + }, + format: :json end before do @@ -316,9 +333,11 @@ describe Projects::IssuesController do describe 'GET #realtime_changes' do def go(id:) get :realtime_changes, - namespace_id: project.namespace.to_param, - project_id: project, - id: id + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: id + } end context 'when an issue was edited' do @@ -431,8 +450,10 @@ describe Projects::IssuesController do def get_issues get :index, - namespace_id: project.namespace.to_param, - project_id: project + params: { + namespace_id: project.namespace.to_param, + project_id: project + } end end @@ -500,7 +521,7 @@ describe Projects::IssuesController do format: :json }.merge(additional_params) - put :update, params + put :update, params: params end def go(id:) @@ -633,9 +654,11 @@ describe Projects::IssuesController do def go(id:) get :show, - namespace_id: project.namespace.to_param, - project_id: project, - id: id + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: id + } end it 'avoids (most) N+1s loading labels', :request_store do @@ -656,9 +679,11 @@ describe Projects::IssuesController do def go(id:) get :realtime_changes, - namespace_id: project.namespace.to_param, - project_id: project, - id: id + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: id + } end end @@ -667,9 +692,11 @@ describe Projects::IssuesController do def go(id:) get :edit, - namespace_id: project.namespace.to_param, - project_id: project, - id: id + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: id + } end end @@ -678,10 +705,12 @@ describe Projects::IssuesController do def go(id:) put :update, - namespace_id: project.namespace.to_param, - project_id: project, - id: id, - issue: { title: 'New title' } + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: id, + issue: { title: 'New title' } + } end end end @@ -692,7 +721,7 @@ describe Projects::IssuesController do project = create(:project, :public) project.add_developer(user) - post :create, { + post :create, params: { namespace_id: project.namespace.to_param, project_id: project, issue: { title: 'Title', description: 'Description' }.merge(issue_attrs) @@ -716,7 +745,7 @@ describe Projects::IssuesController do end def post_issue(issue_params, other_params: {}) - post :create, { namespace_id: project.namespace.to_param, project_id: project, issue: issue_params, merge_request_to_resolve_discussions_of: merge_request.iid }.merge(other_params) + post :create, params: { namespace_id: project.namespace.to_param, project_id: project, issue: issue_params, merge_request_to_resolve_discussions_of: merge_request.iid }.merge(other_params) end it 'creates an issue for the project' do @@ -883,7 +912,7 @@ describe Projects::IssuesController do create(:user_agent_detail, subject: issue) project.add_maintainer(admin) sign_in(admin) - post :mark_as_spam, { + post :mark_as_spam, params: { namespace_id: project.namespace, project_id: project, id: issue.iid @@ -904,7 +933,7 @@ describe Projects::IssuesController do end it "rejects a developer to destroy an issue" do - delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid + delete :destroy, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } expect(response).to have_gitlab_http_status(404) end end @@ -919,7 +948,7 @@ describe Projects::IssuesController do end it "deletes the issue" do - delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid + delete :destroy, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } expect(response).to have_gitlab_http_status(302) expect(controller).to set_flash[:notice].to(/The issue was successfully deleted\./) @@ -928,7 +957,7 @@ describe Projects::IssuesController do it 'delegates the update of the todos count cache to TodoService' do expect_any_instance_of(TodoService).to receive(:destroy_target).with(issue).once - delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid + delete :destroy, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } end end end @@ -941,8 +970,12 @@ describe Projects::IssuesController do it "toggles the award emoji" do expect do - post(:toggle_award_emoji, namespace_id: project.namespace, - project_id: project, id: issue.iid, name: "thumbsup") + post(:toggle_award_emoji, params: { + namespace_id: project.namespace, + project_id: project, + id: issue.iid, + name: "thumbsup" + }) end.to change { issue.award_emoji.count }.by(1) expect(response).to have_gitlab_http_status(200) @@ -984,9 +1017,11 @@ describe Projects::IssuesController do end def create_merge_request - post :create_merge_request, namespace_id: project.namespace.to_param, - project_id: project.to_param, - id: issue.to_param, + post :create_merge_request, params: { + namespace_id: project.namespace.to_param, + project_id: project.to_param, + id: issue.to_param + }, format: :json end end @@ -1000,7 +1035,7 @@ describe Projects::IssuesController do end it 'returns discussion json' do - get :discussions, namespace_id: project.namespace, project_id: project, id: issue.iid + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } expect(json_response.first.keys).to match_array(%w[id reply_id expanded notes diff_discussion discussion_path individual_note resolvable resolved resolved_at resolved_by resolved_by_push commit_id for_commit project_id]) end @@ -1008,7 +1043,7 @@ describe Projects::IssuesController do it 'renders the author status html if there is a status' do create(:user_status, user: discussion.author) - get :discussions, namespace_id: project.namespace, project_id: project, id: issue.iid + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } note_json = json_response.first['notes'].first @@ -1017,14 +1052,14 @@ describe Projects::IssuesController do it 'does not cause an extra query for the status' do control = ActiveRecord::QueryRecorder.new do - get :discussions, namespace_id: project.namespace, project_id: project, id: issue.iid + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } end create(:user_status, user: discussion.author) second_discussion = create(:discussion_note_on_issue, noteable: issue, project: issue.project, author: create(:user)) create(:user_status, user: second_discussion.author) - expect { get :discussions, namespace_id: project.namespace, project_id: project, id: issue.iid } + expect { get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } } .not_to exceed_query_limit(control) end @@ -1044,26 +1079,26 @@ describe Projects::IssuesController do end it 'filters notes that the user should not see' do - get :discussions, namespace_id: project.namespace, project_id: project, id: issue.iid + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } expect(JSON.parse(response.body).count).to eq(1) end it 'does not result in N+1 queries' do # Instantiate the controller variables to ensure QueryRecorder has an accurate base count - get :discussions, namespace_id: project.namespace, project_id: project, id: issue.iid + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } RequestStore.clear! control_count = ActiveRecord::QueryRecorder.new do - get :discussions, namespace_id: project.namespace, project_id: project, id: issue.iid + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } end.count RequestStore.clear! create_list(:discussion_note_on_issue, 2, :system, noteable: issue, project: issue.project, note: cross_reference) - expect { get :discussions, namespace_id: project.namespace, project_id: project, id: issue.iid }.not_to exceed_query_limit(control_count) + expect { get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } }.not_to exceed_query_limit(control_count) end end end diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb index fca313dafb1..7f65fe551e9 100644 --- a/spec/controllers/projects/jobs_controller_spec.rb +++ b/spec/controllers/projects/jobs_controller_spec.rb @@ -96,7 +96,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do project_id: project } - get :index, params.merge(extra_params) + get :index, params: params.merge(extra_params) end end @@ -461,7 +461,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do project_id: project } - get :show, params.merge(extra_params) + get :show, params: params.merge(extra_params) end end @@ -552,9 +552,11 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do end def get_trace - get :trace, namespace_id: project.namespace, - project_id: project, - id: job.id, + get :trace, params: { + namespace_id: project.namespace, + project_id: project, + id: job.id + }, format: :json end end @@ -564,9 +566,11 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do let(:status) { job.detailed_status(double('user')) } before do - get :status, namespace_id: project.namespace, - project_id: project, - id: job.id, + get :status, params: { + namespace_id: project.namespace, + project_id: project, + id: job.id + }, format: :json end @@ -605,9 +609,11 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do end def post_retry - post :retry, namespace_id: project.namespace, - project_id: project, - id: job.id + post :retry, params: { + namespace_id: project.namespace, + project_id: project, + id: job.id + } end end @@ -645,9 +651,11 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do end def post_play - post :play, namespace_id: project.namespace, - project_id: project, - id: job.id + post :play, params: { + namespace_id: project.namespace, + project_id: project, + id: job.id + } end end @@ -714,9 +722,9 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do end def post_cancel(additional_params = {}) - post :cancel, { namespace_id: project.namespace, - project_id: project, - id: job.id }.merge(additional_params) + post :cancel, params: { namespace_id: project.namespace, + project_id: project, + id: job.id }.merge(additional_params) end end @@ -754,9 +762,11 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do end def post_unschedule - post :unschedule, namespace_id: project.namespace, - project_id: project, - id: job.id + post :unschedule, params: { + namespace_id: project.namespace, + project_id: project, + id: job.id + } end end @@ -797,8 +807,10 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do end def post_cancel_all - post :cancel_all, namespace_id: project.namespace, - project_id: project + post :cancel_all, params: { + namespace_id: project.namespace, + project_id: project + } end end @@ -860,52 +872,33 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do end def post_erase - post :erase, namespace_id: project.namespace, - project_id: project, - id: job.id + post :erase, params: { + namespace_id: project.namespace, + project_id: project, + id: job.id + } end end describe 'GET raw' do subject do - post :raw, namespace_id: project.namespace, - project_id: project, - id: job.id + post :raw, params: { + namespace_id: project.namespace, + project_id: project, + id: job.id + } end context "when job has a trace artifact" do let(:job) { create(:ci_build, :trace_artifact, pipeline: pipeline) } - context 'when feature flag workhorse_set_content_type is' do - before do - stub_feature_flags(workhorse_set_content_type: flag_value) - end - - context 'enabled' do - let(:flag_value) { true } - - it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do - response = subject - - expect(response).to have_gitlab_http_status(:ok) - expect(response.headers["Content-Type"]).to eq("text/plain; charset=utf-8") - expect(response.body).to eq(job.job_artifacts_trace.open.read) - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - end - end - - context 'disabled' do - let(:flag_value) { false } - - it 'returns a trace' do - response = subject + it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do + response = subject - expect(response).to have_gitlab_http_status(:ok) - expect(response.headers["Content-Type"]).to eq("text/plain; charset=utf-8") - expect(response.body).to eq(job.job_artifacts_trace.open.read) - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to be nil - end - end + expect(response).to have_gitlab_http_status(:ok) + expect(response.headers["Content-Type"]).to eq("text/plain; charset=utf-8") + expect(response.body).to eq(job.job_artifacts_trace.open.read) + expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" end end @@ -1020,7 +1013,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do project_id: project } - get :terminal, params.merge(extra_params) + get :terminal, params: params.merge(extra_params) end end @@ -1074,7 +1067,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do project_id: project } - get :terminal_websocket_authorize, params.merge(extra_params) + get :terminal_websocket_authorize, params: params.merge(extra_params) end end end diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb index e03d23bcdf6..32897a0f1b4 100644 --- a/spec/controllers/projects/labels_controller_spec.rb +++ b/spec/controllers/projects/labels_controller_spec.rb @@ -67,7 +67,7 @@ describe Projects::LabelsController do end def list_labels - get :index, namespace_id: project.namespace.to_param, project_id: project + get :index, params: { namespace_id: project.namespace.to_param, project_id: project } end end @@ -76,7 +76,7 @@ describe Projects::LabelsController do let(:personal_project) { create(:project, namespace: user.namespace) } it 'creates labels' do - post :generate, namespace_id: personal_project.namespace.to_param, project_id: personal_project + post :generate, params: { namespace_id: personal_project.namespace.to_param, project_id: personal_project } expect(response).to have_gitlab_http_status(302) end @@ -84,7 +84,7 @@ describe Projects::LabelsController do context 'project belonging to a group' do it 'creates labels' do - post :generate, namespace_id: project.namespace.to_param, project_id: project + post :generate, params: { namespace_id: project.namespace.to_param, project_id: project } expect(response).to have_gitlab_http_status(302) end @@ -109,7 +109,7 @@ describe Projects::LabelsController do end def toggle_subscription(label) - post :toggle_subscription, namespace_id: project.namespace.to_param, project_id: project, id: label.to_param + post :toggle_subscription, params: { namespace_id: project.namespace.to_param, project_id: project, id: label.to_param } end end @@ -119,7 +119,7 @@ describe Projects::LabelsController do context 'not group reporters' do it 'denies access' do - post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param + post :promote, params: { namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param } expect(response).to have_gitlab_http_status(404) end @@ -131,13 +131,13 @@ describe Projects::LabelsController do end it 'gives access' do - post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param + post :promote, params: { namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param } expect(response).to redirect_to(namespace_project_labels_path) end it 'promotes the label' do - post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param + post :promote, params: { namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param } expect(Label.where(id: label_1.id)).to be_empty expect(GroupLabel.find_by(title: promoted_label_name)).not_to be_nil @@ -146,7 +146,7 @@ describe Projects::LabelsController do it 'renders label name without parsing it as HTML' do label_1.update!(name: 'CCC<img src=x onerror=alert(document.domain)>') - post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param + post :promote, params: { namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param } expect(flash[:notice]).to eq("CCC<img src=x onerror=alert(document.domain)> promoted to <a href=\"#{group_labels_path(project.group)}\"><u>group label</u></a>.") end @@ -159,7 +159,7 @@ describe Projects::LabelsController do end it 'returns to label list' do - post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param + post :promote, params: { namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param } expect(response).to redirect_to(namespace_project_labels_path) end end @@ -176,7 +176,7 @@ describe Projects::LabelsController do context 'non-show path' do context 'with exactly matching casing' do it 'does not redirect' do - get :index, namespace_id: project.namespace, project_id: project.to_param + get :index, params: { namespace_id: project.namespace, project_id: project.to_param } expect(response).not_to have_gitlab_http_status(301) end @@ -184,7 +184,7 @@ describe Projects::LabelsController do context 'with different casing' do it 'redirects to the correct casing' do - get :index, namespace_id: project.namespace, project_id: project.to_param.upcase + get :index, params: { namespace_id: project.namespace, project_id: project.to_param.upcase } expect(response).to redirect_to(project_labels_path(project)) expect(controller).not_to set_flash[:notice] @@ -197,7 +197,7 @@ describe Projects::LabelsController do let!(:redirect_route) { project.redirect_routes.create(path: project.full_path + 'old') } it 'redirects to the canonical path' do - get :index, namespace_id: project.namespace, project_id: project.to_param + 'old' + get :index, params: { namespace_id: project.namespace, project_id: project.to_param + 'old' } expect(response).to redirect_to(project_labels_path(project)) expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, project)) @@ -209,13 +209,13 @@ describe Projects::LabelsController do context 'for a non-GET request' do context 'when requesting the canonical path with different casing' do it 'does not 404' do - post :generate, namespace_id: project.namespace, project_id: project + post :generate, params: { namespace_id: project.namespace, project_id: project } expect(response).not_to have_gitlab_http_status(404) end it 'does not redirect to the correct casing' do - post :generate, namespace_id: project.namespace, project_id: project + post :generate, params: { namespace_id: project.namespace, project_id: project } expect(response).not_to have_gitlab_http_status(301) end @@ -225,7 +225,7 @@ describe Projects::LabelsController do let!(:redirect_route) { project.redirect_routes.create(path: project.full_path + 'old') } it 'returns not found' do - post :generate, namespace_id: project.namespace, project_id: project.to_param + 'old' + post :generate, params: { namespace_id: project.namespace, project_id: project.to_param + 'old' } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb index c2a334a849c..6c8c7cd8f2b 100644 --- a/spec/controllers/projects/mattermosts_controller_spec.rb +++ b/spec/controllers/projects/mattermosts_controller_spec.rb @@ -17,8 +17,10 @@ describe Projects::MattermostsController do it 'accepts the request' do get(:new, - namespace_id: project.namespace.to_param, - project_id: project) + params: { + namespace_id: project.namespace.to_param, + project_id: project + }) expect(response).to have_gitlab_http_status(200) end @@ -29,9 +31,11 @@ describe Projects::MattermostsController do subject do post(:create, - namespace_id: project.namespace.to_param, - project_id: project, - mattermost: mattermost_params) + params: { + namespace_id: project.namespace.to_param, + project_id: project, + mattermost: mattermost_params + }) end context 'no request can be made to mattermost' do diff --git a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb index 1e1ea9a7144..039f35875d2 100644 --- a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb @@ -21,9 +21,11 @@ describe Projects::MergeRequests::ConflictsController do .and_raise(Gitlab::Git::Conflict::Parser::UnmergeableFile) get :show, - namespace_id: merge_request_with_conflicts.project.namespace.to_param, - project_id: merge_request_with_conflicts.project, - id: merge_request_with_conflicts.iid, + params: { + namespace_id: merge_request_with_conflicts.project.namespace.to_param, + project_id: merge_request_with_conflicts.project, + id: merge_request_with_conflicts.iid + }, format: 'json' end @@ -39,9 +41,11 @@ describe Projects::MergeRequests::ConflictsController do context 'with valid conflicts' do before do get :show, - namespace_id: merge_request_with_conflicts.project.namespace.to_param, - project_id: merge_request_with_conflicts.project, - id: merge_request_with_conflicts.iid, + params: { + namespace_id: merge_request_with_conflicts.project.namespace.to_param, + project_id: merge_request_with_conflicts.project, + id: merge_request_with_conflicts.iid + }, format: 'json' end @@ -99,11 +103,13 @@ describe Projects::MergeRequests::ConflictsController do describe 'GET conflict_for_path' do def conflict_for_path(path) get :conflict_for_path, - namespace_id: merge_request_with_conflicts.project.namespace.to_param, - project_id: merge_request_with_conflicts.project, - id: merge_request_with_conflicts.iid, - old_path: path, - new_path: path, + params: { + namespace_id: merge_request_with_conflicts.project.namespace.to_param, + project_id: merge_request_with_conflicts.project, + id: merge_request_with_conflicts.iid, + old_path: path, + new_path: path + }, format: 'json' end @@ -160,12 +166,14 @@ describe Projects::MergeRequests::ConflictsController do def resolve_conflicts(files) post :resolve_conflicts, - namespace_id: merge_request_with_conflicts.project.namespace.to_param, - project_id: merge_request_with_conflicts.project, - id: merge_request_with_conflicts.iid, - format: 'json', - files: files, - commit_message: 'Commit message' + params: { + namespace_id: merge_request_with_conflicts.project.namespace.to_param, + project_id: merge_request_with_conflicts.project, + id: merge_request_with_conflicts.iid, + files: files, + commit_message: 'Commit message' + }, + format: 'json' end context 'with valid params' do diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb index f8c37c0a676..ac93393ac3a 100644 --- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb @@ -24,7 +24,7 @@ describe Projects::MergeRequests::CreationsController do describe 'GET new' do context 'merge request that removes a submodule' do it 'renders new merge request widget template' do - get :new, get_diff_params + get :new, params: get_diff_params expect(response).to be_success end @@ -52,7 +52,7 @@ describe Projects::MergeRequests::CreationsController do end it 'limits total commits' do - get :new, large_diff_params + get :new, params: large_diff_params expect(response).to be_success @@ -66,7 +66,7 @@ describe Projects::MergeRequests::CreationsController do end it 'shows total commits' do - get :new, large_diff_params + get :new, params: large_diff_params expect(response).to be_success @@ -85,7 +85,7 @@ describe Projects::MergeRequests::CreationsController do it 'does not assign diffs var' do allow_any_instance_of(MergeRequest).to receive(:can_be_created).and_return(false) - get :diffs, get_diff_params.merge(format: 'json') + get :diffs, params: get_diff_params.merge(format: 'json') expect(response).to be_success expect(assigns[:diffs]).to be_nil @@ -101,7 +101,7 @@ describe Projects::MergeRequests::CreationsController do end it 'renders JSON including serialized pipelines' do - get :pipelines, get_diff_params.merge(format: 'json') + get :pipelines, params: get_diff_params.merge(format: 'json') expect(response).to be_ok expect(json_response).to have_key 'pipelines' @@ -117,7 +117,7 @@ describe Projects::MergeRequests::CreationsController do format: 'json' } - get :diff_for_path, params.merge(extra_params) + get :diff_for_path, params: params.merge(extra_params) end let(:existing_path) { 'files/ruby/feature.rb' } @@ -184,10 +184,12 @@ describe Projects::MergeRequests::CreationsController do expect(Ability).to receive(:allowed?).with(user, :read_project, project) { true } get :branch_to, - namespace_id: fork_project.namespace, - project_id: fork_project, - target_project_id: project.id, - ref: 'master' + params: { + namespace_id: fork_project.namespace, + project_id: fork_project, + target_project_id: project.id, + ref: 'master' + } expect(assigns(:commit)).not_to be_nil expect(response).to have_gitlab_http_status(200) @@ -197,10 +199,12 @@ describe Projects::MergeRequests::CreationsController do expect(Ability).to receive(:allowed?).with(user, :read_project, project) { false } get :branch_to, - namespace_id: fork_project.namespace, - project_id: fork_project, - target_project_id: project.id, - ref: 'master' + params: { + namespace_id: fork_project.namespace, + project_id: fork_project, + target_project_id: project.id, + ref: 'master' + } expect(assigns(:commit)).to be_nil expect(response).to have_gitlab_http_status(200) diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb index 8fc5d302af6..a6017d8e5e6 100644 --- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb @@ -20,7 +20,7 @@ describe Projects::MergeRequests::DiffsController do format: 'json' } - get :show, params.merge(extra_params) + get :show, params: params.merge(extra_params) end context 'with default params' do @@ -89,7 +89,7 @@ describe Projects::MergeRequests::DiffsController do format: 'json' } - get :diff_for_path, params.merge(extra_params) + get :diff_for_path, params: params.merge(extra_params) end let(:existing_path) { 'files/ruby/popen.rb' } diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 7f15da859e5..d46b9ffb3ce 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -19,26 +19,17 @@ describe Projects::MergeRequestsController do describe 'GET commit_change_content' do it 'renders commit_change_content template' do get :commit_change_content, - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, format: 'html' expect(response).to render_template('_commit_change_content') end end - shared_examples "loads labels" do |action| - it "loads labels into the @labels variable" do - get action, - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid, - format: 'html' - expect(assigns(:labels)).not_to be_nil - end - end - describe "GET show" do def go(extra_params = {}) params = { @@ -47,11 +38,9 @@ describe Projects::MergeRequestsController do id: merge_request.iid } - get :show, params.merge(extra_params) + get :show, params: params.merge(extra_params) end - it_behaves_like "loads labels", :show - describe 'as html' do context 'when diff files were cleaned' do render_views @@ -153,13 +142,18 @@ describe Projects::MergeRequestsController do def get_merge_requests(page = nil) get :index, - namespace_id: project.namespace.to_param, - project_id: project, - state: 'opened', page: page.to_param + params: { + namespace_id: project.namespace.to_param, + project_id: project, + state: 'opened', + page: page.to_param + } end it_behaves_like "issuables list meta-data", :merge_request + it_behaves_like 'set sort order from user preference' + context 'when page param' do let(:last_page) { project.merge_requests.page().total_pages } let!(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) } @@ -180,11 +174,13 @@ describe Projects::MergeRequestsController do it 'does not redirect to external sites when provided a host field' do external_host = "www.example.com" get :index, - namespace_id: project.namespace.to_param, - project_id: project, - state: 'opened', - page: (last_page + 1).to_param, - host: external_host + params: { + namespace_id: project.namespace.to_param, + project_id: project, + state: 'opened', + page: (last_page + 1).to_param, + host: external_host + } expect(response).to redirect_to(namespace_project_merge_requests_path(page: last_page, state: controller.params[:state], scope: controller.params[:scope])) end @@ -225,7 +221,7 @@ describe Projects::MergeRequestsController do merge_request: mr_params }.merge(additional_params) - put :update, params + put :update, params: params end context 'changing the assignee' do @@ -322,7 +318,7 @@ describe Projects::MergeRequestsController do before do project.add_reporter(user) - xhr :post, :merge, base_params + post :merge, params: base_params, xhr: true end it 'returns 404' do @@ -334,7 +330,7 @@ describe Projects::MergeRequestsController do before do merge_request.update(title: "WIP: #{merge_request.title}") - post :merge, base_params + post :merge, params: base_params end it 'returns :failed' do @@ -344,7 +340,7 @@ describe Projects::MergeRequestsController do context 'when the sha parameter does not match the source SHA' do before do - post :merge, base_params.merge(sha: 'foo') + post :merge, params: base_params.merge(sha: 'foo') end it 'returns :sha_mismatch' do @@ -355,11 +351,7 @@ describe Projects::MergeRequestsController do context 'when the sha parameter matches the source SHA' do def merge_with_sha(params = {}) post_params = base_params.merge(sha: merge_request.diff_head_sha).merge(params) - if Gitlab.rails5? - post :merge, params: post_params, as: :json - else - post :merge, post_params - end + post :merge, params: post_params, as: :json end it 'returns :success' do @@ -398,7 +390,7 @@ describe Projects::MergeRequestsController do end def merge_when_pipeline_succeeds - post :merge, base_params.merge(sha: merge_request.diff_head_sha, merge_when_pipeline_succeeds: '1') + post :merge, params: base_params.merge(sha: merge_request.diff_head_sha, merge_when_pipeline_succeeds: '1') end it 'returns :merge_when_pipeline_succeeds' do @@ -515,7 +507,7 @@ describe Projects::MergeRequestsController 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 + delete :destroy, params: { namespace_id: project.namespace, project_id: project, id: merge_request.iid } expect(response).to have_gitlab_http_status(404) end @@ -530,7 +522,7 @@ describe Projects::MergeRequestsController do end it "deletes the merge request" do - delete :destroy, namespace_id: project.namespace, project_id: project, id: merge_request.iid + delete :destroy, params: { namespace_id: project.namespace, project_id: project, id: merge_request.iid } expect(response).to have_gitlab_http_status(302) expect(controller).to set_flash[:notice].to(/The merge request was successfully deleted\./) @@ -539,7 +531,7 @@ describe Projects::MergeRequestsController do it 'delegates the update of the todos count cache to TodoService' do expect_any_instance_of(TodoService).to receive(:destroy_target).with(merge_request).once - delete :destroy, namespace_id: project.namespace, project_id: project, id: merge_request.iid + delete :destroy, params: { namespace_id: project.namespace, project_id: project, id: merge_request.iid } end end end @@ -547,9 +539,11 @@ describe Projects::MergeRequestsController do describe 'GET commits' do def go(format: 'html') get :commits, - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, format: format end @@ -568,9 +562,11 @@ describe Projects::MergeRequestsController do sha: merge_request.diff_head_sha) get :pipelines, - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, format: :json end @@ -584,9 +580,11 @@ describe Projects::MergeRequestsController do describe 'GET test_reports' do subject do get :test_reports, - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, format: :json end @@ -668,11 +666,14 @@ describe Projects::MergeRequestsController do merge_request.title = merge_request.wip_title merge_request.save - xhr :post, :remove_wip, - namespace_id: merge_request.project.namespace.to_param, - project_id: merge_request.project, - id: merge_request.iid, - format: :json + post :remove_wip, + params: { + format: :json, + namespace_id: merge_request.project.namespace.to_param, + project_id: merge_request.project, + id: merge_request.iid + }, + xhr: true end it 'removes the wip status' do @@ -686,11 +687,14 @@ describe Projects::MergeRequestsController do describe 'POST cancel_merge_when_pipeline_succeeds' do subject do - xhr :post, :cancel_merge_when_pipeline_succeeds, - namespace_id: merge_request.project.namespace.to_param, - project_id: merge_request.project, - id: merge_request.iid, - format: :json + post :cancel_merge_when_pipeline_succeeds, + params: { + format: :json, + namespace_id: merge_request.project.namespace.to_param, + project_id: merge_request.project, + id: merge_request.iid + }, + xhr: true end it 'calls MergeRequests::MergeWhenPipelineSucceedsService' do @@ -725,9 +729,11 @@ describe Projects::MergeRequestsController do target_branch: 'master') post :assign_related_issues, - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + } end it 'shows a flash message on success' do @@ -826,7 +832,7 @@ describe Projects::MergeRequestsController do format: 'json' } - get :ci_environments_status, params.merge(extra_params) + get :ci_environments_status, params: params.merge(extra_params) end end end @@ -867,9 +873,11 @@ describe Projects::MergeRequestsController do end def get_pipeline_status - get :pipeline_status, namespace_id: project.namespace, - project_id: project, - id: merge_request.iid, + get :pipeline_status, params: { + namespace_id: project.namespace, + project_id: project, + id: merge_request.iid + }, format: :json end end @@ -878,7 +886,7 @@ describe Projects::MergeRequestsController do let(:viewer) { user } def post_rebase - post :rebase, namespace_id: project.namespace, project_id: project, id: merge_request + post :rebase, params: { namespace_id: project.namespace, project_id: project, id: merge_request } end def expect_rebase_worker_for(user) @@ -934,15 +942,79 @@ describe Projects::MergeRequestsController do end end + describe 'GET discussions' do + context 'when authenticated' do + before do + project.add_developer(user) + sign_in(user) + end + + it 'returns 200' do + get :discussions, namespace_id: project.namespace, project_id: project, id: merge_request.iid + + expect(response.status).to eq(200) + end + + context 'highlight preloading' do + context 'with commit diff notes' do + let!(:commit_diff_note) do + create(:diff_note_on_commit, project: merge_request.project) + end + + it 'preloads notes diffs highlights' do + expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection| + note_diff_file = commit_diff_note.note_diff_file + + expect(collection).to receive(:load_highlight).with([note_diff_file.id]).and_call_original + expect(collection).to receive(:find_by_id).with(note_diff_file.id).and_call_original + end + + get :discussions, namespace_id: project.namespace, project_id: project, id: merge_request.iid + end + end + + context 'with diff notes' do + let!(:diff_note) do + create(:diff_note_on_merge_request, noteable: merge_request, project: merge_request.project) + end + + it 'preloads notes diffs highlights' do + expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection| + note_diff_file = diff_note.note_diff_file + + expect(collection).to receive(:load_highlight).with([note_diff_file.id]).and_call_original + expect(collection).to receive(:find_by_id).with(note_diff_file.id).and_call_original + end + + get :discussions, namespace_id: project.namespace, project_id: project, id: merge_request.iid + end + + it 'does not preload highlights when diff note is resolved' do + Notes::ResolveService.new(diff_note.project, user).execute(diff_note) + + expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection| + note_diff_file = diff_note.note_diff_file + + expect(collection).to receive(:load_highlight).with([]).and_call_original + expect(collection).to receive(:find_by_id).with(note_diff_file.id).and_call_original + end + + get :discussions, namespace_id: project.namespace, project_id: project, id: merge_request.iid + end + end + end + end + end + describe 'GET edit' do it 'responds successfully' do - get :edit, namespace_id: project.namespace, project_id: project, id: merge_request + get :edit, params: { namespace_id: project.namespace, project_id: project, id: merge_request } expect(response).to have_gitlab_http_status(:success) end it 'assigns the noteable to make sure autocompletes work' do - get :edit, namespace_id: project.namespace, project_id: project, id: merge_request + get :edit, params: { namespace_id: project.namespace, project_id: project, id: merge_request } expect(assigns(:noteable)).not_to be_nil end diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb index 658aa2a6738..5892024e756 100644 --- a/spec/controllers/projects/milestones_controller_spec.rb +++ b/spec/controllers/projects/milestones_controller_spec.rb @@ -22,7 +22,7 @@ describe Projects::MilestonesController do def view_milestone(options = {}) params = { namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid } - get :show, params.merge(options) + get :show, params: params.merge(options) end it 'shows milestone page' do @@ -43,9 +43,11 @@ describe Projects::MilestonesController do describe "#index" do context "as html" do def render_index(project:, page:) - get :index, namespace_id: project.namespace.id, - project_id: project.id, - page: page + get :index, params: { + namespace_id: project.namespace.id, + project_id: project.id, + page: page + } end it "queries only projects milestones" do @@ -90,7 +92,7 @@ describe Projects::MilestonesController do context 'with a single group ancestor' do before do project.update(namespace: group) - get :index, namespace_id: project.namespace.id, project_id: project.id, format: :json + get :index, params: { namespace_id: project.namespace.id, project_id: project.id }, format: :json end it "queries projects milestones and groups milestones" do @@ -107,7 +109,7 @@ describe Projects::MilestonesController do before do project.update(namespace: subgroup) - get :index, namespace_id: project.namespace.id, project_id: project.id, format: :json + get :index, params: { namespace_id: project.namespace.id, project_id: project.id }, format: :json end it "queries projects milestones and all ancestors milestones" do @@ -124,7 +126,7 @@ describe Projects::MilestonesController do it "removes milestone" do expect(issue.milestone_id).to eq(milestone.id) - delete :destroy, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid, format: :js + delete :destroy, params: { namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid }, format: :js expect(response).to be_success expect(Event.recent.first.action).to eq(Event::DESTROYED) @@ -155,7 +157,7 @@ describe Projects::MilestonesController do end it 'renders 404' do - post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid + post :promote, params: { namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid } expect(response).to have_gitlab_http_status(404) end @@ -167,7 +169,7 @@ describe Projects::MilestonesController do end it 'shows group milestone' do - post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid + post :promote, params: { namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid } expect(flash[:notice]).to eq("#{milestone.title} promoted to <a href=\"#{group_milestone_path(project.group, milestone.iid)}\"><u>group milestone</u></a>.") expect(response).to redirect_to(project_milestones_path(project)) @@ -176,7 +178,7 @@ describe Projects::MilestonesController do it 'renders milestone name without parsing it as HTML' do milestone.update!(name: 'CCC<img src=x onerror=alert(document.domain)>') - post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid + post :promote, params: { namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid } expect(flash[:notice]).to eq("CCC promoted to <a href=\"#{group_milestone_path(project.group, milestone.iid)}\"><u>group milestone</u></a>.") end @@ -190,7 +192,7 @@ describe Projects::MilestonesController do it 'renders 404' do project.update(namespace: user.namespace) - post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid + post :promote, params: { namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/projects/mirrors_controller_spec.rb b/spec/controllers/projects/mirrors_controller_spec.rb index 976f480930c..86a12a5e903 100644 --- a/spec/controllers/projects/mirrors_controller_spec.rb +++ b/spec/controllers/projects/mirrors_controller_spec.rb @@ -147,7 +147,7 @@ describe Projects::MirrorsController do end def do_get(project, url = 'ssh://example.com') - get :ssh_host_keys, namespace_id: project.namespace, project_id: project, ssh_url: url + get :ssh_host_keys, params: { namespace_id: project.namespace, project_id: project, ssh_url: url } end end @@ -155,6 +155,6 @@ describe Projects::MirrorsController do attrs = extra_attrs.merge(namespace_id: project.namespace.to_param, project_id: project.to_param) attrs[:project] = options - put :update, attrs + put :update, params: attrs end end diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb index d2a26068362..81892575889 100644 --- a/spec/controllers/projects/notes_controller_spec.rb +++ b/spec/controllers/projects/notes_controller_spec.rb @@ -44,7 +44,7 @@ describe Projects::NotesController do .with(anything, anything, hash_including(last_fetched_at: last_fetched_at)) .and_call_original - get :index, request_params + get :index, params: request_params end context 'when user notes_filter is present' do @@ -55,7 +55,7 @@ describe Projects::NotesController do it 'filters system notes by comments' do user.set_notes_filter(UserPreference::NOTES_FILTERS[:only_comments], issue) - get :index, request_params + get :index, params: request_params expect(notes_json.count).to eq(1) expect(notes_json.first[:id].to_i).to eq(comment.id) @@ -64,7 +64,7 @@ describe Projects::NotesController do it 'returns all notes' do user.set_notes_filter(UserPreference::NOTES_FILTERS[:all_notes], issue) - get :index, request_params + get :index, params: request_params expect(notes_json.map { |note| note[:id].to_i }).to contain_exactly(comment.id, system_note.id) end @@ -74,7 +74,7 @@ describe Projects::NotesController do expect(ResourceEvents::MergeIntoNotesService).not_to receive(:new) - get :index, request_params + get :index, params: request_params end end @@ -85,7 +85,7 @@ describe Projects::NotesController do let(:params) { request_params.merge(target_type: 'merge_request', target_id: note.noteable_id, html: true) } it 'responds with the expected attributes' do - get :index, params + get :index, params: params expect(note_json[:id]).to eq(note.id) expect(note_json[:discussion_html]).not_to be_nil @@ -101,7 +101,7 @@ describe Projects::NotesController do let(:params) { request_params.merge(target_type: 'merge_request', target_id: note.noteable_id, html: true) } it 'responds with the expected attributes' do - get :index, params + get :index, params: params expect(note_json[:id]).to eq(note.id) expect(note_json[:discussion_html]).not_to be_nil @@ -120,7 +120,7 @@ describe Projects::NotesController do let(:params) { request_params.merge(target_type: 'merge_request', target_id: merge_request.id, html: true) } it 'responds with the expected attributes' do - get :index, params + get :index, params: params expect(note_json[:id]).to eq(note.id) expect(note_json[:discussion_html]).not_to be_nil @@ -133,7 +133,7 @@ describe Projects::NotesController do let(:params) { request_params.merge(target_type: 'commit', target_id: note.commit_id, html: true) } it 'responds with the expected attributes' do - get :index, params + get :index, params: params expect(note_json[:id]).to eq(note.id) expect(note_json[:discussion_html]).to be_nil @@ -148,7 +148,7 @@ describe Projects::NotesController do end it 'renders 404' do - get :index, params + get :index, params: params expect(response).to have_gitlab_http_status(404) end @@ -162,7 +162,7 @@ describe Projects::NotesController do let(:params) { request_params.merge(target_type: 'merge_request', target_id: note.noteable_id, html: true) } it 'responds with the expected attributes' do - get :index, params + get :index, params: params expect(note_json[:id]).to eq(note.id) expect(note_json[:html]).not_to be_nil @@ -182,7 +182,7 @@ describe Projects::NotesController do end it 'filters notes that the user should not see' do - get :index, request_params + get :index, params: request_params expect(parsed_response[:notes].count).to eq(1) expect(note_json[:id]).to eq(note.id.to_s) @@ -190,19 +190,19 @@ describe Projects::NotesController do it 'does not result in N+1 queries' do # Instantiate the controller variables to ensure QueryRecorder has an accurate base count - get :index, request_params + get :index, params: request_params RequestStore.clear! control_count = ActiveRecord::QueryRecorder.new do - get :index, request_params + get :index, params: request_params end.count RequestStore.clear! create_list(:discussion_note_on_issue, 2, :system, noteable: issue, project: issue.project, note: cross_reference) - expect { get :index, request_params }.not_to exceed_query_limit(control_count) + expect { get :index, params: request_params }.not_to exceed_query_limit(control_count) end end end @@ -227,19 +227,19 @@ describe Projects::NotesController do end it "returns status 302 for html" do - post :create, request_params + post :create, params: request_params expect(response).to have_gitlab_http_status(302) end it "returns status 200 for json" do - post :create, request_params.merge(format: :json) + post :create, params: request_params.merge(format: :json) expect(response).to have_gitlab_http_status(200) end it 'returns discussion JSON when the return_discussion param is set' do - post :create, request_params.merge(format: :json, return_discussion: 'true') + post :create, params: request_params.merge(format: :json, return_discussion: 'true') expect(response).to have_gitlab_http_status(200) expect(json_response).to have_key 'discussion' @@ -248,19 +248,19 @@ describe Projects::NotesController do context 'when merge_request_diff_head_sha present' do before do - service_params = { + service_params = ActionController::Parameters.new({ note: 'some note', noteable_id: merge_request.id.to_s, noteable_type: 'MergeRequest', merge_request_diff_head_sha: 'sha', in_reply_to_discussion_id: nil - } + }).permit! expect(Notes::CreateService).to receive(:new).with(project, user, service_params).and_return(double(execute: true)) end it "returns status 302 for html" do - post :create, request_params + post :create, params: request_params expect(response).to have_gitlab_http_status(302) end @@ -282,7 +282,7 @@ describe Projects::NotesController do end def post_create(extra_params = {}) - post :create, { + post :create, params: { note: { note: 'some other note', noteable_id: merge_request.id }, namespace_id: project.namespace, project_id: project, @@ -342,7 +342,7 @@ describe Projects::NotesController do namespace_id: project.namespace } - expect { post :create, request_params }.to change { issue.notes.count }.by(1) + expect { post :create, params: request_params }.to change { issue.notes.count }.by(1) .and change { locked_issue.notes.count }.by(0) expect(response).to have_gitlab_http_status(302) end @@ -357,7 +357,7 @@ describe Projects::NotesController do context 'when a noteable is not found' do it 'returns 404 status' do request_params[:target_id] = 9999 - post :create, request_params.merge(format: :json) + post :create, params: request_params.merge(format: :json) expect(response).to have_gitlab_http_status(404) end @@ -365,19 +365,19 @@ describe Projects::NotesController do context 'when a user is a team member' do it 'returns 302 status for html' do - post :create, request_params + post :create, params: request_params expect(response).to have_gitlab_http_status(302) end it 'returns 200 status for json' do - post :create, request_params.merge(format: :json) + post :create, params: request_params.merge(format: :json) expect(response).to have_gitlab_http_status(200) end it 'creates a new note' do - expect { post :create, request_params }.to change { Note.count }.by(1) + expect { post :create, params: request_params }.to change { Note.count }.by(1) end end @@ -387,13 +387,13 @@ describe Projects::NotesController do end it 'returns 404 status' do - post :create, request_params + post :create, params: request_params expect(response).to have_gitlab_http_status(404) end it 'does not create a new note' do - expect { post :create, request_params }.not_to change { Note.count } + expect { post :create, params: request_params }.not_to change { Note.count } end end end @@ -419,7 +419,7 @@ describe Projects::NotesController do end it "updates the note" do - expect { put :update, request_params }.to change { note.reload.note } + expect { put :update, params: request_params }.to change { note.reload.note } end end context "doesnt update the note" do @@ -441,7 +441,7 @@ describe Projects::NotesController do note: "New comment" } } - expect { put :update, request_params }.not_to change { note.reload.note } + expect { put :update, params: request_params }.not_to change { note.reload.note } expect(response).to have_gitlab_http_status(404) end end @@ -464,13 +464,13 @@ describe Projects::NotesController do end it "returns status 200 for html" do - delete :destroy, request_params + delete :destroy, params: request_params expect(response).to have_gitlab_http_status(200) end it "deletes the note" do - expect { delete :destroy, request_params }.to change { Note.count }.from(1).to(0) + expect { delete :destroy, params: request_params }.to change { Note.count }.from(1).to(0) end end @@ -481,7 +481,7 @@ describe Projects::NotesController do end it "returns status 404" do - delete :destroy, request_params + delete :destroy, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -496,17 +496,17 @@ describe Projects::NotesController do it "toggles the award emoji" do expect do - post(:toggle_award_emoji, request_params.merge(name: "thumbsup")) + post(:toggle_award_emoji, params: request_params.merge(name: "thumbsup")) end.to change { note.award_emoji.count }.by(1) expect(response).to have_gitlab_http_status(200) end it "removes the already awarded emoji" do - post(:toggle_award_emoji, request_params.merge(name: "thumbsup")) + post(:toggle_award_emoji, params: request_params.merge(name: "thumbsup")) expect do - post(:toggle_award_emoji, request_params.merge(name: "thumbsup")) + post(:toggle_award_emoji, params: request_params.merge(name: "thumbsup")) end.to change { AwardEmoji.count }.by(-1) expect(response).to have_gitlab_http_status(200) @@ -525,7 +525,7 @@ describe Projects::NotesController do context "when the user is not authorized to resolve the note" do it "returns status 404" do - post :resolve, request_params + post :resolve, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -542,7 +542,7 @@ describe Projects::NotesController do end it "returns status 404" do - post :resolve, request_params + post :resolve, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -550,7 +550,7 @@ describe Projects::NotesController do context "when the note is resolvable" do it "resolves the note" do - post :resolve, request_params + post :resolve, params: request_params expect(note.reload.resolved?).to be true expect(note.reload.resolved_by).to eq(user) @@ -559,17 +559,17 @@ describe Projects::NotesController do it "sends notifications if all discussions are resolved" do expect_any_instance_of(MergeRequests::ResolvedDiscussionNotificationService).to receive(:execute).with(merge_request) - post :resolve, request_params + post :resolve, params: request_params end it "returns the name of the resolving user" do - post :resolve, request_params.merge(html: true) + post :resolve, params: request_params.merge(html: true) expect(JSON.parse(response.body)["resolved_by"]).to eq(user.name) end it "returns status 200" do - post :resolve, request_params + post :resolve, params: request_params expect(response).to have_gitlab_http_status(200) end @@ -586,7 +586,7 @@ describe Projects::NotesController do context "when the user is not authorized to resolve the note" do it "returns status 404" do - delete :unresolve, request_params + delete :unresolve, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -603,7 +603,7 @@ describe Projects::NotesController do end it "returns status 404" do - delete :unresolve, request_params + delete :unresolve, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -611,13 +611,13 @@ describe Projects::NotesController do context "when the note is resolvable" do it "unresolves the note" do - delete :unresolve, request_params + delete :unresolve, params: request_params expect(note.reload.resolved?).to be false end it "returns status 200" do - delete :unresolve, request_params + delete :unresolve, params: request_params expect(response).to have_gitlab_http_status(200) end diff --git a/spec/controllers/projects/pages_controller_spec.rb b/spec/controllers/projects/pages_controller_spec.rb index 927b6e0c473..382c1b5d124 100644 --- a/spec/controllers/projects/pages_controller_spec.rb +++ b/spec/controllers/projects/pages_controller_spec.rb @@ -19,7 +19,7 @@ describe Projects::PagesController do describe 'GET show' do it 'returns 200 status' do - get :show, request_params + get :show, params: request_params expect(response).to have_gitlab_http_status(200) end @@ -29,7 +29,7 @@ describe Projects::PagesController do let(:project) { create(:project, namespace: group) } it 'returns a 404 status code' do - get :show, request_params + get :show, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -38,7 +38,7 @@ describe Projects::PagesController do describe 'DELETE destroy' do it 'returns 302 status' do - delete :destroy, request_params + delete :destroy, params: request_params expect(response).to have_gitlab_http_status(302) end @@ -51,7 +51,7 @@ describe Projects::PagesController do describe 'GET show' do it 'returns 404 status' do - get :show, request_params + get :show, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -59,7 +59,7 @@ describe Projects::PagesController do describe 'DELETE destroy' do it 'returns 404 status' do - delete :destroy, request_params + delete :destroy, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -82,13 +82,13 @@ describe Projects::PagesController do end it 'returns 302 status' do - patch :update, request_params + patch :update, params: request_params expect(response).to have_gitlab_http_status(:found) end it 'redirects back to the pages settings' do - patch :update, request_params + patch :update, params: request_params expect(response).to redirect_to(project_pages_path(project)) end @@ -99,7 +99,7 @@ describe Projects::PagesController do .with(project, user, ActionController::Parameters.new(request_params[:project]).permit!) .and_return(update_service) - patch :update, request_params + patch :update, params: request_params end end end diff --git a/spec/controllers/projects/pages_domains_controller_spec.rb b/spec/controllers/projects/pages_domains_controller_spec.rb index 75871eab1ab..8b7f7587701 100644 --- a/spec/controllers/projects/pages_domains_controller_spec.rb +++ b/spec/controllers/projects/pages_domains_controller_spec.rb @@ -24,7 +24,7 @@ describe Projects::PagesDomainsController do describe 'GET show' do it "displays the 'show' page" do - get(:show, request_params.merge(id: pages_domain.domain)) + get(:show, params: request_params.merge(id: pages_domain.domain)) expect(response).to have_gitlab_http_status(200) expect(response).to render_template('show') @@ -33,7 +33,7 @@ describe Projects::PagesDomainsController do describe 'GET new' do it "displays the 'new' page" do - get(:new, request_params) + get(:new, params: request_params) expect(response).to have_gitlab_http_status(200) expect(response).to render_template('new') @@ -43,7 +43,7 @@ describe Projects::PagesDomainsController do describe 'POST create' do it "creates a new pages domain" do expect do - post(:create, request_params.merge(pages_domain: pages_domain_params)) + post(:create, params: request_params.merge(pages_domain: pages_domain_params)) end.to change { PagesDomain.count }.by(1) created_domain = PagesDomain.reorder(:id).last @@ -55,7 +55,7 @@ describe Projects::PagesDomainsController do describe 'GET edit' do it "displays the 'edit' page" do - get(:edit, request_params.merge(id: pages_domain.domain)) + get(:edit, params: request_params.merge(id: pages_domain.domain)) expect(response).to have_gitlab_http_status(200) expect(response).to render_template('edit') @@ -78,14 +78,14 @@ describe Projects::PagesDomainsController do it 'updates the domain' do expect(pages_domain) .to receive(:update) - .with(pages_domain_params) + .with(ActionController::Parameters.new(pages_domain_params).permit!) .and_return(true) - patch(:update, params) + patch(:update, params: params) end it 'redirects to the project page' do - patch(:update, params) + patch(:update, params: params) expect(flash[:notice]).to eq 'Domain was updated' expect(response).to redirect_to(project_pages_path(project)) @@ -95,7 +95,7 @@ describe Projects::PagesDomainsController do it 'renders the edit action' do allow(pages_domain).to receive(:update).and_return(false) - patch(:update, params) + patch(:update, params: params) expect(response).to render_template('edit') end @@ -108,7 +108,7 @@ describe Projects::PagesDomainsController do .with(hash_not_including(:domain)) .and_return(true) - patch(:update, params.deep_merge(pages_domain: { domain: 'abc' })) + patch(:update, params: params.deep_merge(pages_domain: { domain: 'abc' })) end end end @@ -127,7 +127,7 @@ describe Projects::PagesDomainsController do it 'handles verification success' do expect(stub_service).to receive(:execute).and_return(status: :success) - post :verify, params + post :verify, params: params expect(response).to redirect_to project_pages_domain_path(project, pages_domain) expect(flash[:notice]).to eq('Successfully verified domain ownership') @@ -136,14 +136,14 @@ describe Projects::PagesDomainsController do it 'handles verification failure' do expect(stub_service).to receive(:execute).and_return(status: :failed) - post :verify, params + post :verify, params: params expect(response).to redirect_to project_pages_domain_path(project, pages_domain) expect(flash[:alert]).to eq('Failed to verify domain ownership') end it 'returns a 404 response for an unknown domain' do - post :verify, request_params.merge(id: 'unknown-domain') + post :verify, params: request_params.merge(id: 'unknown-domain') expect(response).to have_gitlab_http_status(404) end @@ -152,7 +152,7 @@ describe Projects::PagesDomainsController do describe 'DELETE destroy' do it "deletes the pages domain" do expect do - delete(:destroy, request_params.merge(id: pages_domain.domain)) + delete(:destroy, params: request_params.merge(id: pages_domain.domain)) end.to change { PagesDomain.count }.by(-1) expect(response).to redirect_to(project_pages_path(project)) @@ -166,7 +166,7 @@ describe Projects::PagesDomainsController do describe 'GET show' do it 'returns 404 status' do - get(:show, request_params.merge(id: pages_domain.domain)) + get(:show, params: request_params.merge(id: pages_domain.domain)) expect(response).to have_gitlab_http_status(404) end @@ -174,7 +174,7 @@ describe Projects::PagesDomainsController do describe 'GET new' do it 'returns 404 status' do - get :new, request_params + get :new, params: request_params expect(response).to have_gitlab_http_status(404) end @@ -182,7 +182,7 @@ describe Projects::PagesDomainsController do describe 'POST create' do it "returns 404 status" do - post(:create, request_params.merge(pages_domain: pages_domain_params)) + post(:create, params: request_params.merge(pages_domain: pages_domain_params)) expect(response).to have_gitlab_http_status(404) end @@ -190,7 +190,7 @@ describe Projects::PagesDomainsController do describe 'DELETE destroy' do it "deletes the pages domain" do - delete(:destroy, request_params.merge(id: pages_domain.domain)) + delete(:destroy, params: request_params.merge(id: pages_domain.domain)) expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb index 7179423dde2..80506249ea9 100644 --- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb +++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb @@ -44,7 +44,7 @@ describe Projects::PipelineSchedulesController do end def visit_pipelines_schedules - get :index, namespace_id: project.namespace.to_param, project_id: project, scope: scope + get :index, params: { namespace_id: project.namespace.to_param, project_id: project, scope: scope } end end @@ -57,7 +57,7 @@ describe Projects::PipelineSchedulesController do end it 'initializes a pipeline schedule model' do - get :new, namespace_id: project.namespace.to_param, project_id: project + get :new, params: { namespace_id: project.namespace.to_param, project_id: project } expect(response).to have_gitlab_http_status(:ok) expect(assigns(:schedule)).to be_a_new(Ci::PipelineSchedule) @@ -131,7 +131,7 @@ describe Projects::PipelineSchedulesController do end def go - post :create, namespace_id: project.namespace.to_param, project_id: project, schedule: schedule + post :create, params: { namespace_id: project.namespace.to_param, project_id: project, schedule: schedule } end end @@ -310,19 +310,11 @@ describe Projects::PipelineSchedulesController do end def go - if Gitlab.rails5? - put :update, params: { namespace_id: project.namespace.to_param, - project_id: project, - id: pipeline_schedule, - schedule: schedule }, - as: :html - - else - put :update, namespace_id: project.namespace.to_param, - project_id: project, - id: pipeline_schedule, - schedule: schedule - end + put :update, params: { namespace_id: project.namespace.to_param, + project_id: project, + id: pipeline_schedule, + schedule: schedule }, + as: :html end end @@ -336,7 +328,7 @@ describe Projects::PipelineSchedulesController do end it 'loads the pipeline schedule' do - get :edit, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + get :edit, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id } expect(response).to have_gitlab_http_status(:ok) expect(assigns(:schedule)).to eq(pipeline_schedule) @@ -356,7 +348,7 @@ describe Projects::PipelineSchedulesController do end def go - get :edit, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + get :edit, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id } end end @@ -374,7 +366,7 @@ describe Projects::PipelineSchedulesController do end def go - post :take_ownership, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + post :take_ownership, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id } end end @@ -396,7 +388,7 @@ describe Projects::PipelineSchedulesController do it 'does not allow pipeline to be executed' do expect(RunPipelineScheduleWorker).not_to receive(:perform_async) - post :play, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + post :play, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id } expect(response).to have_gitlab_http_status(404) end @@ -406,7 +398,7 @@ describe Projects::PipelineSchedulesController do it 'executes a new pipeline' do expect(RunPipelineScheduleWorker).to receive(:perform_async).with(pipeline_schedule.id, user.id).and_return('job-123') - post :play, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + post :play, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id } expect(flash[:notice]).to start_with 'Successfully scheduled a pipeline to run' expect(response).to have_gitlab_http_status(302) @@ -414,7 +406,7 @@ describe Projects::PipelineSchedulesController do it 'prevents users from scheduling the same pipeline repeatedly' do 2.times do - post :play, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + post :play, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id } end expect(flash.to_a.size).to eq(2) @@ -430,7 +422,7 @@ describe Projects::PipelineSchedulesController do expect(RunPipelineScheduleWorker).not_to receive(:perform_async) - post :play, namespace_id: project.namespace.to_param, project_id: project, id: protected_schedule.id + post :play, params: { namespace_id: project.namespace.to_param, project_id: project, id: protected_schedule.id } expect(response).to have_gitlab_http_status(404) end @@ -445,7 +437,7 @@ describe Projects::PipelineSchedulesController do project.add_developer(user) sign_in(user) - delete :destroy, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + delete :destroy, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id } end it 'does not delete the pipeline schedule' do @@ -461,7 +453,7 @@ describe Projects::PipelineSchedulesController do it 'destroys the pipeline schedule' do expect do - delete :destroy, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + delete :destroy, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id } end.to change { project.pipeline_schedules.count }.by(-1) expect(response).to have_gitlab_http_status(302) diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 5c7415a318d..0bb3ef76a3b 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -119,8 +119,10 @@ describe Projects::PipelinesController do end def get_pipelines_index_json - get :index, namespace_id: project.namespace, - project_id: project, + get :index, params: { + namespace_id: project.namespace, + project_id: project + }, format: :json end @@ -185,7 +187,7 @@ describe Projects::PipelinesController do end def get_pipeline_json - get :show, namespace_id: project.namespace, project_id: project, id: pipeline, format: :json + get :show, params: { namespace_id: project.namespace, project_id: project, id: pipeline }, format: :json end def create_build(stage, stage_idx, name) @@ -240,12 +242,14 @@ describe Projects::PipelinesController do end def get_stage(name, params = {}) - get :stage, **params.merge( - namespace_id: project.namespace, - project_id: project, - id: pipeline.id, - stage: name, - format: :json) + get :stage, params: { +**params.merge( + namespace_id: project.namespace, + project_id: project, + id: pipeline.id, + stage: name, + format: :json) +} end end @@ -277,10 +281,12 @@ describe Projects::PipelinesController do end def get_stage_ajax(name) - get :stage_ajax, namespace_id: project.namespace, - project_id: project, - id: pipeline.id, - stage: name, + get :stage_ajax, params: { + namespace_id: project.namespace, + project_id: project, + id: pipeline.id, + stage: name + }, format: :json end end @@ -290,9 +296,11 @@ describe Projects::PipelinesController do let(:status) { pipeline.detailed_status(double('user')) } before do - get :status, namespace_id: project.namespace, - project_id: project, - id: pipeline.id, + get :status, params: { + namespace_id: project.namespace, + project_id: project, + id: pipeline.id + }, format: :json end @@ -310,9 +318,11 @@ describe Projects::PipelinesController do let!(:build) { create(:ci_build, :failed, pipeline: pipeline) } before do - post :retry, namespace_id: project.namespace, - project_id: project, - id: pipeline.id, + post :retry, params: { + namespace_id: project.namespace, + project_id: project, + id: pipeline.id + }, format: :json end @@ -337,9 +347,11 @@ describe Projects::PipelinesController do let!(:build) { create(:ci_build, :running, pipeline: pipeline) } before do - post :cancel, namespace_id: project.namespace, - project_id: project, - id: pipeline.id, + post :cancel, params: { + namespace_id: project.namespace, + project_id: project, + id: pipeline.id + }, format: :json end diff --git a/spec/controllers/projects/pipelines_settings_controller_spec.rb b/spec/controllers/projects/pipelines_settings_controller_spec.rb index b1ba9f74e38..269f105bed2 100644 --- a/spec/controllers/projects/pipelines_settings_controller_spec.rb +++ b/spec/controllers/projects/pipelines_settings_controller_spec.rb @@ -13,7 +13,7 @@ describe Projects::PipelinesSettingsController do describe 'GET show' do it 'redirects with 302 status code' do - get :show, namespace_id: project.namespace, project_id: project + get :show, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(302) end diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index 519af10d78c..3cc3fe69fba 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::ProjectMembersController do describe 'GET index' do it 'should have the project_members address with a 200 status code' do - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(200) end @@ -25,10 +25,12 @@ describe Projects::ProjectMembersController do end it 'returns 404' do - post :create, namespace_id: project.namespace, - project_id: project, - user_ids: project_user.id, - access_level: Gitlab::Access::GUEST + post :create, params: { + namespace_id: project.namespace, + project_id: project, + user_ids: project_user.id, + access_level: Gitlab::Access::GUEST + } expect(response).to have_gitlab_http_status(404) expect(project.users).not_to include project_user @@ -43,10 +45,12 @@ describe Projects::ProjectMembersController do it 'adds user to members' do expect_any_instance_of(Members::CreateService).to receive(:execute).and_return(status: :success) - post :create, namespace_id: project.namespace, - project_id: project, - user_ids: project_user.id, - access_level: Gitlab::Access::GUEST + post :create, params: { + namespace_id: project.namespace, + project_id: project, + user_ids: project_user.id, + access_level: Gitlab::Access::GUEST + } expect(response).to set_flash.to 'Users were successfully added.' expect(response).to redirect_to(project_project_members_path(project)) @@ -55,10 +59,12 @@ describe Projects::ProjectMembersController do it 'adds no user to members' do expect_any_instance_of(Members::CreateService).to receive(:execute).and_return(status: :failure, message: 'Message') - post :create, namespace_id: project.namespace, - project_id: project, - user_ids: '', - access_level: Gitlab::Access::GUEST + post :create, params: { + namespace_id: project.namespace, + project_id: project, + user_ids: '', + access_level: Gitlab::Access::GUEST + } expect(response).to set_flash.to 'Message' expect(response).to redirect_to(project_project_members_path(project)) @@ -76,10 +82,12 @@ describe Projects::ProjectMembersController do Gitlab::Access.options.each do |label, value| it "can change the access level to #{label}" do - xhr :put, :update, project_member: { access_level: value }, - namespace_id: project.namespace, - project_id: project, - id: requester + put :update, params: { + project_member: { access_level: value }, + namespace_id: project.namespace, + project_id: project, + id: requester + }, xhr: true expect(requester.reload.human_access).to eq(label) end @@ -95,9 +103,11 @@ describe Projects::ProjectMembersController do context 'when member is not found' do it 'returns 404' do - delete :destroy, namespace_id: project.namespace, - project_id: project, - id: 42 + delete :destroy, params: { + namespace_id: project.namespace, + project_id: project, + id: 42 + } expect(response).to have_gitlab_http_status(404) end @@ -110,9 +120,11 @@ describe Projects::ProjectMembersController do end it 'returns 404' do - delete :destroy, namespace_id: project.namespace, - project_id: project, - id: member + delete :destroy, params: { + namespace_id: project.namespace, + project_id: project, + id: member + } expect(response).to have_gitlab_http_status(404) expect(project.members).to include member @@ -125,9 +137,11 @@ describe Projects::ProjectMembersController do end it '[HTML] removes user from members' do - delete :destroy, namespace_id: project.namespace, - project_id: project, - id: member + delete :destroy, params: { + namespace_id: project.namespace, + project_id: project, + id: member + } expect(response).to redirect_to( project_project_members_path(project) @@ -136,9 +150,11 @@ describe Projects::ProjectMembersController do end it '[JS] removes user from members' do - xhr :delete, :destroy, namespace_id: project.namespace, - project_id: project, - id: member + delete :destroy, params: { + namespace_id: project.namespace, + project_id: project, + id: member + }, xhr: true expect(response).to be_success expect(project.members).not_to include member @@ -154,8 +170,10 @@ describe Projects::ProjectMembersController do context 'when member is not found' do it 'returns 404' do - delete :leave, namespace_id: project.namespace, - project_id: project + delete :leave, params: { + namespace_id: project.namespace, + project_id: project + } expect(response).to have_gitlab_http_status(404) end @@ -168,8 +186,10 @@ describe Projects::ProjectMembersController do end it 'removes user from members' do - delete :leave, namespace_id: project.namespace, - project_id: project + delete :leave, params: { + namespace_id: project.namespace, + project_id: project + } expect(response).to set_flash.to "You left the \"#{project.human_name}\" project." expect(response).to redirect_to(dashboard_projects_path) @@ -185,8 +205,10 @@ describe Projects::ProjectMembersController do end it 'cannot remove themselves from the project' do - delete :leave, namespace_id: project.namespace, - project_id: project + delete :leave, params: { + namespace_id: project.namespace, + project_id: project + } expect(response).to have_gitlab_http_status(403) end @@ -198,8 +220,10 @@ describe Projects::ProjectMembersController do end it 'removes user from members' do - delete :leave, namespace_id: project.namespace, - project_id: project + delete :leave, params: { + namespace_id: project.namespace, + project_id: project + } expect(response).to set_flash.to 'Your access request to the project has been withdrawn.' expect(response).to redirect_to(project_path(project)) @@ -216,8 +240,10 @@ describe Projects::ProjectMembersController do end it 'creates a new ProjectMember that is not a team member' do - post :request_access, namespace_id: project.namespace, - project_id: project + post :request_access, params: { + namespace_id: project.namespace, + project_id: project + } expect(response).to set_flash.to 'Your request for access has been queued for review.' expect(response).to redirect_to( @@ -237,9 +263,11 @@ describe Projects::ProjectMembersController do context 'when member is not found' do it 'returns 404' do - post :approve_access_request, namespace_id: project.namespace, - project_id: project, - id: 42 + post :approve_access_request, params: { + namespace_id: project.namespace, + project_id: project, + id: 42 + } expect(response).to have_gitlab_http_status(404) end @@ -252,9 +280,11 @@ describe Projects::ProjectMembersController do end it 'returns 404' do - post :approve_access_request, namespace_id: project.namespace, - project_id: project, - id: member + post :approve_access_request, params: { + namespace_id: project.namespace, + project_id: project, + id: member + } expect(response).to have_gitlab_http_status(404) expect(project.members).not_to include member @@ -267,9 +297,11 @@ describe Projects::ProjectMembersController do end it 'adds user to members' do - post :approve_access_request, namespace_id: project.namespace, - project_id: project, - id: member + post :approve_access_request, params: { + namespace_id: project.namespace, + project_id: project, + id: member + } expect(response).to redirect_to( project_project_members_path(project) @@ -292,9 +324,11 @@ describe Projects::ProjectMembersController do shared_context 'import applied' do before do - post(:apply_import, namespace_id: project.namespace, - project_id: project, - source_project_id: another_project.id) + post(:apply_import, params: { + namespace_id: project.namespace, + project_id: project, + source_project_id: another_project.id + }) end end @@ -338,10 +372,12 @@ describe Projects::ProjectMembersController do it 'does not create a member' do expect do - post :create, user_ids: stranger.id, - namespace_id: project.namespace, - access_level: Member::OWNER, - project_id: project + post :create, params: { + user_ids: stranger.id, + namespace_id: project.namespace, + access_level: Member::OWNER, + project_id: project + } end.to change { project.members.count }.by(0) end end @@ -354,10 +390,12 @@ describe Projects::ProjectMembersController do it 'creates a member' do expect do - post :create, user_ids: stranger.id, - namespace_id: project.namespace, - access_level: Member::MAINTAINER, - project_id: project + post :create, params: { + user_ids: stranger.id, + namespace_id: project.namespace, + access_level: Member::MAINTAINER, + project_id: project + } end.to change { project.members.count }.by(1) end end diff --git a/spec/controllers/projects/prometheus/metrics_controller_spec.rb b/spec/controllers/projects/prometheus/metrics_controller_spec.rb index 5c56a712245..635763ce1d3 100644 --- a/spec/controllers/projects/prometheus/metrics_controller_spec.rb +++ b/spec/controllers/projects/prometheus/metrics_controller_spec.rb @@ -24,7 +24,7 @@ describe Projects::Prometheus::MetricsController do end it 'returns no content response' do - get :active_common, project_params(format: :json) + get :active_common, params: project_params(format: :json) expect(response).to have_gitlab_http_status(204) end @@ -38,7 +38,7 @@ describe Projects::Prometheus::MetricsController do end it 'returns no content response' do - get :active_common, project_params(format: :json) + get :active_common, params: project_params(format: :json) expect(response).to have_gitlab_http_status(200) expect(json_response).to eq(sample_response.deep_stringify_keys) @@ -47,7 +47,7 @@ describe Projects::Prometheus::MetricsController do context 'when requesting non json response' do it 'returns not found response' do - get :active_common, project_params + get :active_common, params: project_params expect(response).to have_gitlab_http_status(404) end @@ -62,7 +62,7 @@ describe Projects::Prometheus::MetricsController do allow(controller).to receive(:prometheus_adapter).and_return(prometheus_adapter) allow(prometheus_adapter).to receive(:query).with(:matched_metrics).and_return({}) - get :active_common, project_params(format: :json) + get :active_common, params: project_params(format: :json) expect(response).to have_gitlab_http_status(404) end @@ -70,7 +70,7 @@ describe Projects::Prometheus::MetricsController do context 'when prometheus_adapter is disabled' do it 'renders 404' do - get :active_common, project_params(format: :json) + get :active_common, params: project_params(format: :json) expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/projects/protected_branches_controller_spec.rb b/spec/controllers/projects/protected_branches_controller_spec.rb index ac812707e74..483d3bbc37c 100644 --- a/spec/controllers/projects/protected_branches_controller_spec.rb +++ b/spec/controllers/projects/protected_branches_controller_spec.rb @@ -15,7 +15,7 @@ describe Projects::ProtectedBranchesController do let(:project) { create(:project_empty_repo, :public) } it "redirects empty repo to projects page" do - get(:index, namespace_id: project.namespace.to_param, project_id: project) + get(:index, params: { namespace_id: project.namespace.to_param, project_id: project }) end end @@ -33,7 +33,7 @@ describe Projects::ProtectedBranchesController do it 'creates the protected branch rule' do expect do - post(:create, project_params.merge(protected_branch: create_params)) + post(:create, params: project_params.merge(protected_branch: create_params)) end.to change(ProtectedBranch, :count).by(1) end @@ -44,7 +44,7 @@ describe Projects::ProtectedBranchesController do end it "prevents creation of the protected branch rule" do - post(:create, project_params.merge(protected_branch: create_params)) + post(:create, params: project_params.merge(protected_branch: create_params)) expect(ProtectedBranch.count).to eq 0 end @@ -59,7 +59,7 @@ describe Projects::ProtectedBranchesController do end it 'updates the protected branch rule' do - put(:update, base_params.merge(protected_branch: update_params)) + put(:update, params: base_params.merge(protected_branch: update_params)) expect(protected_branch.reload.name).to eq('new_name') expect(json_response["name"]).to eq('new_name') @@ -74,7 +74,7 @@ describe Projects::ProtectedBranchesController do it "prevents update of the protected branch rule" do old_name = protected_branch.name - put(:update, base_params.merge(protected_branch: update_params)) + put(:update, params: base_params.merge(protected_branch: update_params)) expect(protected_branch.reload.name).to eq(old_name) end @@ -87,7 +87,7 @@ describe Projects::ProtectedBranchesController do end it "deletes the protected branch rule" do - delete(:destroy, base_params) + delete(:destroy, params: base_params) expect { ProtectedBranch.find(protected_branch.id) }.to raise_error(ActiveRecord::RecordNotFound) end @@ -99,7 +99,7 @@ describe Projects::ProtectedBranchesController do end it "prevents deletion of the protected branch rule" do - delete(:destroy, base_params) + delete(:destroy, params: base_params) expect(response.status).to eq(403) end diff --git a/spec/controllers/projects/protected_tags_controller_spec.rb b/spec/controllers/projects/protected_tags_controller_spec.rb index 20440c5a5d5..1553e081dee 100644 --- a/spec/controllers/projects/protected_tags_controller_spec.rb +++ b/spec/controllers/projects/protected_tags_controller_spec.rb @@ -5,7 +5,7 @@ describe Projects::ProtectedTagsController do let(:project) { create(:project_empty_repo, :public) } it "redirects empty repo to projects page" do - get(:index, namespace_id: project.namespace.to_param, project_id: project) + get(:index, params: { namespace_id: project.namespace.to_param, project_id: project }) end end @@ -20,7 +20,7 @@ describe Projects::ProtectedTagsController do end it "deletes the protected tag" do - delete(:destroy, namespace_id: project.namespace.to_param, project_id: project, id: protected_tag.id) + delete(:destroy, params: { namespace_id: project.namespace.to_param, project_id: project, id: protected_tag.id }) expect { ProtectedTag.find(protected_tag.id) }.to raise_error(ActiveRecord::RecordNotFound) end diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb index d3cd15fbcd7..cffdf30da6b 100644 --- a/spec/controllers/projects/raw_controller_spec.rb +++ b/spec/controllers/projects/raw_controller_spec.rb @@ -6,82 +6,37 @@ describe Projects::RawController do describe 'GET #show' do subject do get(:show, - namespace_id: project.namespace, - project_id: project, - id: filepath) + params: { + namespace_id: project.namespace, + project_id: project, + id: filepath + }) end context 'regular filename' do let(:filepath) { 'master/README.md' } - context 'when feature flag workhorse_set_content_type is' do - before do - stub_feature_flags(workhorse_set_content_type: flag_value) + it 'delivers ASCII file' do + subject - subject - end - - context 'enabled' do - let(:flag_value) { true } - - it 'delivers ASCII file' do - expect(response).to have_gitlab_http_status(200) - expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8') - expect(response.header['Content-Disposition']).to eq('inline') - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') - end - end - - context 'disabled' do - let(:flag_value) { false } - - it 'delivers ASCII file' do - expect(response).to have_gitlab_http_status(200) - expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8') - expect(response.header['Content-Disposition']).to eq('inline') - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq nil - expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') - end - end + expect(response).to have_gitlab_http_status(200) + expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8') + expect(response.header['Content-Disposition']).to eq('inline') + expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" + expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') end end context 'image header' do let(:filepath) { 'master/files/images/6049019_460s.jpg' } - context 'when feature flag workhorse_set_content_type is' do - before do - stub_feature_flags(workhorse_set_content_type: flag_value) - end - - context 'enabled' do - let(:flag_value) { true } - - it 'leaves image content disposition' do - subject - - expect(response).to have_gitlab_http_status(200) - expect(response.header['Content-Type']).to eq('image/jpeg') - expect(response.header['Content-Disposition']).to eq('inline') - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') - end - end - - context 'disabled' do - let(:flag_value) { false } - - it 'sets image content type header' do - subject + it 'leaves image content disposition' do + subject - expect(response).to have_gitlab_http_status(200) - expect(response.header['Content-Type']).to eq('image/jpeg') - expect(response.header['Content-Disposition']).to eq('inline') - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq nil - expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') - end - end + expect(response).to have_gitlab_http_status(200) + expect(response.header['Content-Disposition']).to eq('inline') + expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" + expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') end end diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb index ceaffd92623..62f2af947e4 100644 --- a/spec/controllers/projects/refs_controller_spec.rb +++ b/spec/controllers/projects/refs_controller_spec.rb @@ -12,21 +12,23 @@ describe Projects::RefsController do describe 'GET #logs_tree' do def default_get(format = :html) get :logs_tree, - namespace_id: project.namespace.to_param, - project_id: project, - id: 'master', - path: 'foo/bar/baz.html', + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: 'master', + path: 'foo/bar/baz.html' + }, format: format end def xhr_get(format = :html) - xhr :get, - :logs_tree, - namespace_id: project.namespace.to_param, - project_id: project, - id: 'master', - path: 'foo/bar/baz.html', - format: format + get :logs_tree, params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: 'master', + path: 'foo/bar/baz.html', + format: format + }, xhr: true end it 'never throws MissingTemplate' do diff --git a/spec/controllers/projects/registry/repositories_controller_spec.rb b/spec/controllers/projects/registry/repositories_controller_spec.rb index d11e42b411b..eca187af33d 100644 --- a/spec/controllers/projects/registry/repositories_controller_spec.rb +++ b/spec/controllers/projects/registry/repositories_controller_spec.rb @@ -111,15 +111,19 @@ describe Projects::Registry::RepositoriesController do end def go_to_index(format: :html) - get :index, namespace_id: project.namespace, - project_id: project, + get :index, params: { + namespace_id: project.namespace, + project_id: project + }, format: format end def delete_repository(repository) - delete :destroy, namespace_id: project.namespace, - project_id: project, - id: repository, + delete :destroy, params: { + namespace_id: project.namespace, + project_id: project, + id: repository + }, format: :json end end diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb index 7fee8fd44ff..ed0197afcfc 100644 --- a/spec/controllers/projects/registry/tags_controller_spec.rb +++ b/spec/controllers/projects/registry/tags_controller_spec.rb @@ -65,9 +65,11 @@ describe Projects::Registry::TagsController do private def get_tags - get :index, namespace_id: project.namespace, - project_id: project, - repository_id: repository, + get :index, params: { + namespace_id: project.namespace, + project_id: project, + repository_id: repository + }, format: :json end end @@ -100,10 +102,12 @@ describe Projects::Registry::TagsController do private def destroy_tag(name) - post :destroy, namespace_id: project.namespace, - project_id: project, - repository_id: repository, - id: name, + post :destroy, params: { + namespace_id: project.namespace, + project_id: project, + repository_id: repository, + id: name + }, format: :json end end diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb index 20a6beb3df8..f170a2ab613 100644 --- a/spec/controllers/projects/releases_controller_spec.rb +++ b/spec/controllers/projects/releases_controller_spec.rb @@ -1,55 +1,65 @@ +# frozen_string_literal: true + require 'spec_helper' describe Projects::ReleasesController do - let!(:project) { create(:project, :repository) } + let!(:project) { create(:project, :repository, :public) } let!(:user) { create(:user) } - let!(:release) { create(:release, project: project) } - let!(:tag) { release.tag } before do - project.add_developer(user) - sign_in(user) + stub_feature_flags(releases_page: true) end - describe 'GET #edit' do - it 'initializes a new release' do - tag_id = release.tag - project.releases.destroy_all # rubocop: disable DestroyAll - - get :edit, namespace_id: project.namespace, project_id: project, tag_id: tag_id + describe 'GET #index' do + it 'renders a 200' do + get_index - release = assigns(:release) - expect(release).not_to be_nil - expect(release).not_to be_persisted + expect(response.status).to eq(200) end - it 'retrieves an existing release' do - get :edit, namespace_id: project.namespace, project_id: project, tag_id: release.tag + context 'when the project is private' do + let!(:project) { create(:project, :repository, :private) } - release = assigns(:release) - expect(release).not_to be_nil - expect(release).to be_persisted - end - end + it 'renders a 302' do + get_index + + expect(response.status).to eq(302) + end + + it 'renders a 200 for a logged in developer' do + project.add_developer(user) + sign_in(user) - describe 'PUT #update' do - it 'updates release note description' do - update_release('description updated') + get_index - release = project.releases.find_by_tag(tag) - expect(release.description).to eq("description updated") + expect(response.status).to eq(200) + end + + it 'renders a 404 when logged in but not in the project' do + sign_in(user) + + get_index + + expect(response.status).to eq(404) + end end - it 'deletes release note when description is null' do - expect { update_release('') }.to change(project.releases, :count).by(-1) + context 'when releases_page feature flag is disabled' do + before do + stub_feature_flags(releases_page: false) + end + + it 'renders a 404' do + get_index + + expect(response.status).to eq(404) + end end end - def update_release(description) - put :update, - namespace_id: project.namespace.to_param, - project_id: project, - tag_id: release.tag, - release: { description: description } + private + + def get_index + get :index, params: { namespace_id: project.namespace, project_id: project } end end diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb index a102a3a3c8c..5f4f6f8558f 100644 --- a/spec/controllers/projects/repositories_controller_spec.rb +++ b/spec/controllers/projects/repositories_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::RepositoriesController do describe "GET archive" do context 'as a guest' do it 'responds with redirect in correct format' do - get :archive, namespace_id: project.namespace, project_id: project, id: "master", format: "zip" + get :archive, params: { namespace_id: project.namespace, project_id: project, id: "master" }, format: "zip" expect(response.header["Content-Type"]).to start_with('text/html') expect(response).to be_redirect @@ -22,26 +22,26 @@ describe Projects::RepositoriesController do end it "uses Gitlab::Workhorse" do - get :archive, namespace_id: project.namespace, project_id: project, id: "master", format: "zip" + get :archive, params: { namespace_id: project.namespace, project_id: project, id: "master" }, format: "zip" expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-archive:") end it 'responds with redirect to the short name archive if fully qualified' do - get :archive, namespace_id: project.namespace, project_id: project, id: "master/#{project.path}-master", format: "zip" + get :archive, params: { namespace_id: project.namespace, project_id: project, id: "master/#{project.path}-master" }, format: "zip" expect(assigns(:ref)).to eq("master") expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-archive:") end it 'handles legacy queries with no ref' do - get :archive, namespace_id: project.namespace, project_id: project, format: "zip" + get :archive, params: { namespace_id: project.namespace, project_id: project }, format: "zip" expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-archive:") end it 'handles legacy queries with the ref specified as ref in params' do - get :archive, namespace_id: project.namespace, project_id: project, ref: 'feature', format: 'zip' + get :archive, params: { namespace_id: project.namespace, project_id: project, ref: 'feature' }, format: 'zip' expect(response).to have_gitlab_http_status(200) expect(assigns(:ref)).to eq('feature') @@ -49,7 +49,7 @@ describe Projects::RepositoriesController do end it 'handles legacy queries with the ref specified as id in params' do - get :archive, namespace_id: project.namespace, project_id: project, id: 'feature', format: 'zip' + get :archive, params: { namespace_id: project.namespace, project_id: project, id: 'feature' }, format: 'zip' expect(response).to have_gitlab_http_status(200) expect(assigns(:ref)).to eq('feature') @@ -57,7 +57,7 @@ describe Projects::RepositoriesController do end it 'prioritizes the id param over the ref param when both are specified' do - get :archive, namespace_id: project.namespace, project_id: project, id: 'feature', ref: 'feature_conflict', format: 'zip' + get :archive, params: { namespace_id: project.namespace, project_id: project, id: 'feature', ref: 'feature_conflict' }, format: 'zip' expect(response).to have_gitlab_http_status(200) expect(assigns(:ref)).to eq('feature') @@ -70,7 +70,7 @@ describe Projects::RepositoriesController do end it "renders Not Found" do - get :archive, namespace_id: project.namespace, project_id: project, id: "master", format: "zip" + get :archive, params: { namespace_id: project.namespace, project_id: project, id: "master" }, format: "zip" expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb index b1e0b496ede..0baaa4e7192 100644 --- a/spec/controllers/projects/runners_controller_spec.rb +++ b/spec/controllers/projects/runners_controller_spec.rb @@ -23,7 +23,7 @@ describe Projects::RunnersController do new_desc = runner.description.swapcase expect do - post :update, params.merge(runner: { description: new_desc } ) + post :update, params: params.merge(runner: { description: new_desc } ) end.to change { runner.ensure_runner_queue_value } runner.reload @@ -35,7 +35,7 @@ describe Projects::RunnersController do describe '#destroy' do it 'destroys the runner' do - delete :destroy, params + delete :destroy, params: params expect(response).to have_gitlab_http_status(302) expect(Ci::Runner.find_by(id: runner.id)).to be_nil @@ -47,7 +47,7 @@ describe Projects::RunnersController do runner.update(active: false) expect do - post :resume, params + post :resume, params: params end.to change { runner.ensure_runner_queue_value } runner.reload @@ -62,7 +62,7 @@ describe Projects::RunnersController do runner.update(active: true) expect do - post :pause, params + post :pause, params: params end.to change { runner.ensure_runner_queue_value } runner.reload diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb index 284b582b1f5..a9759c4fbd8 100644 --- a/spec/controllers/projects/serverless/functions_controller_spec.rb +++ b/spec/controllers/projects/serverless/functions_controller_spec.rb @@ -32,13 +32,13 @@ describe Projects::Serverless::FunctionsController do describe 'GET #index' do context 'empty cache' do it 'has no data' do - get :index, params({ format: :json }) + get :index, params: params({ format: :json }) expect(response).to have_gitlab_http_status(204) end it 'renders an html page' do - get :index, params + get :index, params: params expect(response).to have_gitlab_http_status(200) end @@ -51,7 +51,7 @@ describe Projects::Serverless::FunctionsController do end it 'has data' do - get :index, params({ format: :json }) + get :index, params: params({ format: :json }) expect(response).to have_gitlab_http_status(200) @@ -64,7 +64,7 @@ describe Projects::Serverless::FunctionsController do end it 'has data in html' do - get :index, params + get :index, params: params expect(response).to have_gitlab_http_status(200) end diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb index 45cea8c1351..4a5d2bdecb7 100644 --- a/spec/controllers/projects/services_controller_spec.rb +++ b/spec/controllers/projects/services_controller_spec.rb @@ -3,9 +3,8 @@ require 'spec_helper' describe Projects::ServicesController do let(:project) { create(:project, :repository) } let(:user) { create(:user) } - let(:service) { create(:hipchat_service, project: project) } - let(:hipchat_client) { { '#room' => double(send: true) } } - let(:service_params) { { token: 'hipchat_token_p', room: '#room' } } + let(:service) { create(:jira_service, project: project) } + let(:service_params) { { username: 'username', password: 'password', url: 'http://example.com' } } before do sign_in(user) @@ -17,20 +16,20 @@ describe Projects::ServicesController do it 'renders 404' do allow_any_instance_of(Service).to receive(:can_test?).and_return(false) - put :test, namespace_id: project.namespace, project_id: project, id: service.to_param + put :test, params: { namespace_id: project.namespace, project_id: project, id: service.to_param } expect(response).to have_gitlab_http_status(404) end end context 'when validations fail' do - let(:service_params) { { active: 'true', token: '' } } + let(:service_params) { { active: 'true', url: '' } } it 'returns error messages in JSON response' do - put :test, namespace_id: project.namespace, project_id: project, id: :hipchat, service: service_params + put :test, params: { namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params } expect(json_response['message']).to eq "Validations failed." - expect(json_response['service_response']).to eq "Token can't be blank" + expect(json_response['service_response']).to include "Url can't be blank" expect(response).to have_gitlab_http_status(200) end end @@ -45,25 +44,27 @@ describe Projects::ServicesController do it 'returns success' do allow_any_instance_of(MicrosoftTeams::Notifier).to receive(:ping).and_return(true) - put :test, namespace_id: project.namespace, project_id: project, id: service.to_param + put :test, params: { namespace_id: project.namespace, project_id: project, id: service.to_param } expect(response.status).to eq(200) end end it 'returns success' do - expect(HipChat::Client).to receive(:new).with('hipchat_token_p', anything).and_return(hipchat_client) + stub_request(:get, 'http://example.com/rest/api/2/serverInfo') + .to_return(status: 200, body: '{}') - put :test, namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params + put :test, params: { namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params } expect(response.status).to eq(200) end end it 'returns success' do - expect(HipChat::Client).to receive(:new).with('hipchat_token_p', anything).and_return(hipchat_client) + stub_request(:get, 'http://example.com/rest/api/2/serverInfo') + .to_return(status: 200, body: '{}') - put :test, namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params + put :test, params: { namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params } expect(response.status).to eq(200) end @@ -76,33 +77,44 @@ describe Projects::ServicesController do it 'persist the object' do do_put + expect(response).to have_gitlab_http_status(200) + expect(json_response).to be_empty expect(BuildkiteService.first).to be_present end it 'creates the ServiceHook object' do do_put + expect(response).to have_gitlab_http_status(200) + expect(json_response).to be_empty expect(BuildkiteService.first.service_hook).to be_present end def do_put - put :test, namespace_id: project.namespace, - project_id: project, - id: 'buildkite', - service: { 'active' => '1', 'push_events' => '1', token: 'token', 'project_url' => 'http://test.com' } + put :test, params: { + namespace_id: project.namespace, + project_id: project, + id: 'buildkite', + service: { 'active' => '1', 'push_events' => '1', token: 'token', 'project_url' => 'http://test.com' } + } end end end context 'failure' do it 'returns success status code and the error message' do - expect(HipChat::Client).to receive(:new).with('hipchat_token_p', anything).and_raise('Bad test') + stub_request(:get, 'http://example.com/rest/api/2/serverInfo') + .to_return(status: 404) - put :test, namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params + put :test, params: { namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params } - expect(response.status).to eq(200) - expect(JSON.parse(response.body)) - .to eq('error' => true, 'message' => 'Test failed.', 'service_response' => 'Bad test', 'test_failed' => true) + expect(response).to have_gitlab_http_status(200) + expect(json_response).to eq( + 'error' => true, + 'message' => 'Test failed.', + 'service_response' => '', + 'test_failed' => true + ) end end end @@ -111,19 +123,19 @@ describe Projects::ServicesController do context 'when param `active` is set to true' do it 'activates the service and redirects to integrations paths' do put :update, - namespace_id: project.namespace, project_id: project, id: service.to_param, service: { active: true } + params: { namespace_id: project.namespace, project_id: project, id: service.to_param, service: { active: true } } expect(response).to redirect_to(project_settings_integrations_path(project)) - expect(flash[:notice]).to eq 'HipChat activated.' + expect(flash[:notice]).to eq 'JIRA activated.' end end context 'when param `active` is set to false' do it 'does not activate the service but saves the settings' do put :update, - namespace_id: project.namespace, project_id: project, id: service.to_param, service: { active: false } + params: { namespace_id: project.namespace, project_id: project, id: service.to_param, service: { active: false } } - expect(flash[:notice]).to eq 'HipChat settings saved, but not activated.' + expect(flash[:notice]).to eq 'JIRA settings saved, but not activated.' end end @@ -132,7 +144,7 @@ describe Projects::ServicesController do before do put :update, - namespace_id: project.namespace, project_id: project, id: service.to_param, service: { namespace: 'updated_namespace' } + params: { namespace_id: project.namespace, project_id: project, id: service.to_param, service: { namespace: 'updated_namespace' } } end it 'should not update the service' do @@ -144,7 +156,7 @@ describe Projects::ServicesController do describe "GET #edit" do before do - get :edit, namespace_id: project.namespace, project_id: project, id: service_id + get :edit, params: { namespace_id: project.namespace, project_id: project, id: service_id } end context 'with approved services' do diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb index 4629929f9af..41cc0607cee 100644 --- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb @@ -12,7 +12,7 @@ describe Projects::Settings::CiCdController do describe 'GET show' do it 'renders show with 200 status code' do - get :show, namespace_id: project.namespace, project_id: project + get :show, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:show) @@ -29,7 +29,7 @@ describe Projects::Settings::CiCdController do it 'sets assignable project runners only' do group.add_maintainer(user) - get :show, namespace_id: project.namespace, project_id: project + get :show, params: { namespace_id: project.namespace, project_id: project } expect(assigns(:assignable_runners)).to contain_exactly(project_runner) end @@ -45,7 +45,7 @@ describe Projects::Settings::CiCdController do allow(ResetProjectCacheService).to receive_message_chain(:new, :execute).and_return(true) end - subject { post :reset_cache, namespace_id: project.namespace, project_id: project, format: :json } + subject { post :reset_cache, params: { namespace_id: project.namespace, project_id: project }, format: :json } it 'calls reset project cache service' do expect(ResetProjectCacheService).to receive_message_chain(:new, :execute) @@ -75,7 +75,7 @@ describe Projects::Settings::CiCdController do end describe 'PUT #reset_registration_token' do - subject { put :reset_registration_token, namespace_id: project.namespace, project_id: project } + subject { put :reset_registration_token, params: { namespace_id: project.namespace, project_id: project } } it 'resets runner registration token' do expect { subject }.to change { project.reload.runners_token } end @@ -92,9 +92,11 @@ describe Projects::Settings::CiCdController do subject do patch :update, - namespace_id: project.namespace.to_param, - project_id: project, - project: params + params: { + namespace_id: project.namespace.to_param, + project_id: project, + project: params + } end it 'redirects to the settings page' do diff --git a/spec/controllers/projects/settings/integrations_controller_spec.rb b/spec/controllers/projects/settings/integrations_controller_spec.rb index a2484c04c7a..8624eb4d1a0 100644 --- a/spec/controllers/projects/settings/integrations_controller_spec.rb +++ b/spec/controllers/projects/settings/integrations_controller_spec.rb @@ -11,7 +11,7 @@ describe Projects::Settings::IntegrationsController do describe 'GET show' do it 'renders show with 200 status code' do - get :show, namespace_id: project.namespace, project_id: project + get :show, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:show) diff --git a/spec/controllers/projects/settings/repository_controller_spec.rb b/spec/controllers/projects/settings/repository_controller_spec.rb index 70f79a47e63..638cce60a25 100644 --- a/spec/controllers/projects/settings/repository_controller_spec.rb +++ b/spec/controllers/projects/settings/repository_controller_spec.rb @@ -11,7 +11,7 @@ describe Projects::Settings::RepositoryController do describe 'GET show' do it 'renders show with 200 status code' do - get :show, namespace_id: project.namespace, project_id: project + get :show, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:show) @@ -19,35 +19,15 @@ describe Projects::Settings::RepositoryController do end describe 'PUT cleanup' do - before do - allow(RepositoryCleanupWorker).to receive(:perform_async) - end - - def do_put! - object_map = fixture_file_upload('spec/fixtures/bfg_object_map.txt') - - put :cleanup, namespace_id: project.namespace, project_id: project, project: { object_map: object_map } - end + let(:object_map) { fixture_file_upload('spec/fixtures/bfg_object_map.txt') } - context 'feature enabled' do - it 'enqueues a RepositoryCleanupWorker' do - stub_feature_flags(project_cleanup: true) - - do_put! - - expect(response).to redirect_to project_settings_repository_path(project) - expect(RepositoryCleanupWorker).to have_received(:perform_async).once - end - end - - context 'feature disabled' do - it 'shows a 404 error' do - stub_feature_flags(project_cleanup: false) + it 'enqueues a RepositoryCleanupWorker' do + allow(RepositoryCleanupWorker).to receive(:perform_async) - do_put! + put :cleanup, params: { namespace_id: project.namespace, project_id: project, project: { object_map: object_map } } - expect(response).to have_gitlab_http_status(404) - end + expect(response).to redirect_to project_settings_repository_path(project) + expect(RepositoryCleanupWorker).to have_received(:perform_async).once end end end diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb index 9c383bd7628..e4b78aff25d 100644 --- a/spec/controllers/projects/snippets_controller_spec.rb +++ b/spec/controllers/projects/snippets_controller_spec.rb @@ -17,16 +17,22 @@ describe Projects::SnippetsController do it 'redirects to last_page if page number is larger than number of pages' do get :index, - namespace_id: project.namespace, - project_id: project, page: (last_page + 1).to_param + params: { + namespace_id: project.namespace, + project_id: project, + page: (last_page + 1).to_param + } expect(response).to redirect_to(namespace_project_snippets_path(page: last_page)) end it 'redirects to specified page' do get :index, - namespace_id: project.namespace, - project_id: project, page: last_page.to_param + params: { + namespace_id: project.namespace, + project_id: project, + page: last_page.to_param + } expect(assigns(:snippets).current_page).to eq(last_page) expect(response).to have_gitlab_http_status(200) @@ -38,7 +44,7 @@ describe Projects::SnippetsController do context 'when anonymous' do it 'does not include the private snippet' do - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } expect(assigns(:snippets)).not_to include(project_snippet) expect(response).to have_gitlab_http_status(200) @@ -51,7 +57,7 @@ describe Projects::SnippetsController do end it 'renders the snippet' do - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } expect(assigns(:snippets)).to include(project_snippet) expect(response).to have_gitlab_http_status(200) @@ -64,7 +70,7 @@ describe Projects::SnippetsController do end it 'renders the snippet' do - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } expect(assigns(:snippets)).to include(project_snippet) expect(response).to have_gitlab_http_status(200) @@ -79,7 +85,7 @@ describe Projects::SnippetsController do project.add_developer(user) - post :create, { + post :create, params: { namespace_id: project.namespace.to_param, project_id: project, project_snippet: { title: 'Title', content: 'Content', description: 'Description' }.merge(snippet_params) @@ -164,7 +170,7 @@ describe Projects::SnippetsController do project.add_developer(user) - put :update, { + put :update, params: { namespace_id: project.namespace.to_param, project_id: project, id: snippet.id, @@ -295,9 +301,11 @@ describe Projects::SnippetsController do sign_in(admin) post :mark_as_spam, - namespace_id: project.namespace, - project_id: project, - id: snippet.id + params: { + namespace_id: project.namespace, + project_id: project, + id: snippet.id + } end it 'updates the snippet' do @@ -314,7 +322,7 @@ describe Projects::SnippetsController do context 'when anonymous' do it 'responds with status 404' do - get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param + get action, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param } expect(response).to have_gitlab_http_status(404) end @@ -326,7 +334,7 @@ describe Projects::SnippetsController do end it 'renders the snippet' do - get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param + get action, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param } expect(assigns(:snippet)).to eq(project_snippet) expect(response).to have_gitlab_http_status(200) @@ -339,7 +347,7 @@ describe Projects::SnippetsController do end it 'renders the snippet' do - get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param + get action, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param } expect(assigns(:snippet)).to eq(project_snippet) expect(response).to have_gitlab_http_status(200) @@ -350,7 +358,7 @@ describe Projects::SnippetsController do context 'when the project snippet does not exist' do context 'when anonymous' do it 'responds with status 404' do - get action, namespace_id: project.namespace, project_id: project, id: 42 + get action, params: { namespace_id: project.namespace, project_id: project, id: 42 } expect(response).to have_gitlab_http_status(404) end @@ -362,7 +370,7 @@ describe Projects::SnippetsController do end it 'responds with status 404' do - get action, namespace_id: project.namespace, project_id: project, id: 42 + get action, params: { namespace_id: project.namespace, project_id: project, id: 42 } expect(response).to have_gitlab_http_status(404) end @@ -371,6 +379,46 @@ describe Projects::SnippetsController do end end + describe "GET #show for embeddable content" do + let(:project_snippet) { create(:project_snippet, snippet_permission, project: project, author: user) } + + before do + sign_in(user) + + get :show, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param, format: :js + end + + context 'when snippet is private' do + let(:snippet_permission) { :private } + + it 'responds with status 404' do + expect(response).to have_gitlab_http_status(404) + end + end + + context 'when snippet is public' do + let(:snippet_permission) { :public } + + it 'responds with status 200' do + expect(assigns(:snippet)).to eq(project_snippet) + expect(response).to have_gitlab_http_status(200) + end + end + + context 'when the project is private' do + let(:project) { create(:project_empty_repo, :private) } + + context 'when snippet is public' do + let(:project_snippet) { create(:project_snippet, :public, project: project, author: user) } + + it 'responds with status 404' do + expect(assigns(:snippet)).to eq(project_snippet) + expect(response).to have_gitlab_http_status(404) + end + end + end + end + describe 'GET #raw' do let(:project_snippet) do create( @@ -391,13 +439,13 @@ describe Projects::SnippetsController do end it 'returns LF line endings by default' do - get :raw, params + get :raw, params: params expect(response.body).to eq("first line\nsecond line\nthird line") end it 'does not convert line endings when parameter present' do - get :raw, params.merge(line_ending: :raw) + get :raw, params: params.merge(line_ending: :raw) expect(response.body).to eq("first line\r\nsecond line\r\nthird line") end diff --git a/spec/controllers/projects/tags/releases_controller_spec.rb b/spec/controllers/projects/tags/releases_controller_spec.rb new file mode 100644 index 00000000000..29f206c574b --- /dev/null +++ b/spec/controllers/projects/tags/releases_controller_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Projects::Tags::ReleasesController do + let!(:project) { create(:project, :repository) } + let!(:user) { create(:user) } + let!(:release) { create(:release, project: project) } + let!(:tag) { release.tag } + + before do + project.add_developer(user) + sign_in(user) + end + + describe 'GET #edit' do + it 'initializes a new release' do + tag_id = release.tag + project.releases.destroy_all # rubocop: disable DestroyAll + + get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: tag_id } + + release = assigns(:release) + expect(release).not_to be_nil + expect(release).not_to be_persisted + end + + it 'retrieves an existing release' do + get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: release.tag } + + release = assigns(:release) + expect(release).not_to be_nil + expect(release).to be_persisted + end + end + + describe 'PUT #update' do + it 'updates release note description' do + update_release('description updated') + + release = project.releases.find_by_tag(tag) + expect(release.description).to eq("description updated") + end + + it 'deletes release note when description is null' do + expect { update_release('') }.to change(project.releases, :count).by(-1) + end + end + + def update_release(description) + put :update, params: { + namespace_id: project.namespace.to_param, + project_id: project, + tag_id: release.tag, + release: { description: description } + } + end +end diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb index 6fbf75d0259..379430bff3b 100644 --- a/spec/controllers/projects/tags_controller_spec.rb +++ b/spec/controllers/projects/tags_controller_spec.rb @@ -7,7 +7,7 @@ describe Projects::TagsController do describe 'GET index' do before do - get :index, namespace_id: project.namespace.to_param, project_id: project + get :index, params: { namespace_id: project.namespace.to_param, project_id: project } end it 'returns the tags for the page' do @@ -22,7 +22,7 @@ describe Projects::TagsController do describe 'GET show' do before do - get :show, namespace_id: project.namespace.to_param, project_id: project, id: id + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, id: id } end context "valid tag" do diff --git a/spec/controllers/projects/templates_controller_spec.rb b/spec/controllers/projects/templates_controller_spec.rb index d7f07aa2b01..01e53669627 100644 --- a/spec/controllers/projects/templates_controller_spec.rb +++ b/spec/controllers/projects/templates_controller_spec.rb @@ -20,7 +20,7 @@ describe Projects::TemplatesController do describe '#show' do it 'renders template name and content as json' do - get(:show, namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project, format: :json) + get(:show, params: { namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project }, format: :json) expect(response.status).to eq(200) expect(body["name"]).to eq("bug") @@ -29,21 +29,21 @@ describe Projects::TemplatesController do it 'renders 404 when unauthorized' do sign_in(user2) - get(:show, namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project, format: :json) + get(:show, params: { namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project }, format: :json) expect(response.status).to eq(404) end it 'renders 404 when template type is not found' do sign_in(user) - get(:show, namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project, format: :json) + get(:show, params: { namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project }, format: :json) expect(response.status).to eq(404) end it 'renders 404 without errors' do sign_in(user) - expect { get(:show, namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project, format: :json) }.not_to raise_error + expect { get(:show, params: { namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project }, format: :json) }.not_to raise_error end end end diff --git a/spec/controllers/projects/todos_controller_spec.rb b/spec/controllers/projects/todos_controller_spec.rb index 58f2817c7cc..987772f38aa 100644 --- a/spec/controllers/projects/todos_controller_spec.rb +++ b/spec/controllers/projects/todos_controller_spec.rb @@ -29,10 +29,12 @@ describe Projects::TodosController do describe 'POST create' do def post_create post :create, - namespace_id: project.namespace, - project_id: project, - issuable_id: issue.id, - issuable_type: 'issue', + params: { + namespace_id: project.namespace, + project_id: project, + issuable_id: issue.id, + issuable_type: 'issue' + }, format: 'html' end @@ -44,10 +46,12 @@ describe Projects::TodosController do describe 'POST create' do def post_create post :create, - namespace_id: project.namespace, - project_id: project, - issuable_id: merge_request.id, - issuable_type: 'merge_request', + params: { + namespace_id: project.namespace, + project_id: project, + issuable_id: merge_request.id, + issuable_type: 'merge_request' + }, format: 'html' end diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb index 9982b49eebb..b15a2bc84a5 100644 --- a/spec/controllers/projects/tree_controller_spec.rb +++ b/spec/controllers/projects/tree_controller_spec.rb @@ -17,9 +17,11 @@ describe Projects::TreeController do before do get(:show, - namespace_id: project.namespace.to_param, - project_id: project, - id: id) + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: id + }) end context "valid branch, no path" do @@ -73,9 +75,11 @@ describe Projects::TreeController do before do get(:show, - namespace_id: project.namespace.to_param, - project_id: project, - id: id) + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: id + }) end context 'redirect to blob' do @@ -93,12 +97,14 @@ describe Projects::TreeController do before do post(:create_dir, - namespace_id: project.namespace.to_param, - project_id: project, - id: 'master', - dir_name: path, - branch_name: branch_name, - commit_message: 'Test commit message') + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: 'master', + dir_name: path, + branch_name: branch_name, + commit_message: 'Test commit message' + }) end context 'successful creation' do diff --git a/spec/controllers/projects/uploads_controller_spec.rb b/spec/controllers/projects/uploads_controller_spec.rb index 9802e4d5b1e..cfa67683dd3 100644 --- a/spec/controllers/projects/uploads_controller_spec.rb +++ b/spec/controllers/projects/uploads_controller_spec.rb @@ -12,7 +12,7 @@ describe Projects::UploadsController do context 'when the URL the old style, without /-/system' do it 'responds with a redirect to the login page' do - get :show, namespace_id: 'project', project_id: 'avatar', filename: 'foo.png', secret: 'bar' + get :show, params: { namespace_id: 'project', project_id: 'avatar', filename: 'foo.png', secret: 'bar' } expect(response).to redirect_to(new_user_session_path) end @@ -35,6 +35,6 @@ describe Projects::UploadsController do def post_authorize(verified: true) request.headers.merge!(workhorse_internal_api_request_header) if verified - post :authorize, namespace_id: model.namespace, project_id: model.path, format: :json + post :authorize, params: { namespace_id: model.namespace, project_id: model.path }, format: :json end end diff --git a/spec/controllers/projects/variables_controller_spec.rb b/spec/controllers/projects/variables_controller_spec.rb index 9afd1f751c6..8cceda72c28 100644 --- a/spec/controllers/projects/variables_controller_spec.rb +++ b/spec/controllers/projects/variables_controller_spec.rb @@ -13,7 +13,7 @@ describe Projects::VariablesController do let!(:variable) { create(:ci_variable, project: project) } subject do - get :show, namespace_id: project.namespace.to_param, project_id: project, format: :json + get :show, params: { namespace_id: project.namespace.to_param, project_id: project }, format: :json end include_examples 'GET #show lists all variables' @@ -25,9 +25,11 @@ describe Projects::VariablesController do subject do patch :update, - namespace_id: project.namespace.to_param, - project_id: project, - variables_attributes: variables_attributes, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + variables_attributes: variables_attributes + }, format: :json end diff --git a/spec/controllers/projects/wikis_controller_spec.rb b/spec/controllers/projects/wikis_controller_spec.rb index b974d927856..b2f40231796 100644 --- a/spec/controllers/projects/wikis_controller_spec.rb +++ b/spec/controllers/projects/wikis_controller_spec.rb @@ -20,7 +20,7 @@ describe Projects::WikisController do describe 'GET #show' do render_views - subject { get :show, namespace_id: project.namespace, project_id: project, id: wiki_title } + subject { get :show, params: { namespace_id: project.namespace, project_id: project, id: wiki_title } } it 'limits the retrieved pages for the sidebar' do expect(controller).to receive(:load_wiki).and_return(project_wiki) @@ -52,56 +52,24 @@ describe Projects::WikisController do let(:path) { upload_file_to_wiki(project, user, file_name) } - subject { get :show, namespace_id: project.namespace, project_id: project, id: path } + before do + get :show, params: { namespace_id: project.namespace, project_id: project, id: path } + end context 'when file is an image' do let(:file_name) { 'dk.png' } - context 'when feature flag workhorse_set_content_type is' do - before do - stub_feature_flags(workhorse_set_content_type: flag_value) - - subject - end - - context 'enabled' do - let(:flag_value) { true } - - it 'delivers the image' do - expect(response.headers['Content-Type']).to eq('image/png') - expect(response.headers['Content-Disposition']).to match(/^inline/) - expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - end - - context 'when file is a svg' do - let(:file_name) { 'unsanitized.svg' } - - it 'delivers the image' do - expect(response.headers['Content-Type']).to eq('image/svg+xml') - expect(response.headers['Content-Disposition']).to match(/^attachment/) - expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - end - end - end - - context 'disabled' do - let(:flag_value) { false } - - it 'renders the content inline' do - expect(response.headers['Content-Type']).to eq('image/png') - expect(response.headers['Content-Disposition']).to match(/^inline/) - expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq nil - end + it 'delivers the image' do + expect(response.headers['Content-Disposition']).to match(/^inline/) + expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" + end - context 'when file is a svg' do - let(:file_name) { 'unsanitized.svg' } + context 'when file is a svg' do + let(:file_name) { 'unsanitized.svg' } - it 'renders the content as an attachment' do - expect(response.headers['Content-Type']).to eq('image/svg+xml') - expect(response.headers['Content-Disposition']).to match(/^attachment/) - expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq nil - end - end + it 'delivers the image' do + expect(response.headers['Content-Disposition']).to match(/^inline/) + expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" end end end @@ -109,32 +77,9 @@ describe Projects::WikisController do context 'when file is a pdf' do let(:file_name) { 'git-cheat-sheet.pdf' } - context 'when feature flag workhorse_set_content_type is' do - before do - stub_feature_flags(workhorse_set_content_type: flag_value) - - subject - end - - context 'enabled' do - let(:flag_value) { true } - - it 'sets the content type to sets the content response headers' do - expect(response.headers['Content-Type']).to eq 'application/octet-stream' - expect(response.headers['Content-Disposition']).to match(/^inline/) - expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - end - end - - context 'disabled' do - let(:flag_value) { false } - - it 'sets the content response headers' do - expect(response.headers['Content-Type']).to eq 'application/octet-stream' - expect(response.headers['Content-Disposition']).to match(/^inline/) - expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq nil - end - end + it 'sets the content type to sets the content response headers' do + expect(response.headers['Content-Disposition']).to match(/^inline/) + expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" end end end @@ -142,14 +87,14 @@ describe Projects::WikisController do describe 'POST #preview_markdown' do it 'renders json in a correct format' do - post :preview_markdown, namespace_id: project.namespace, project_id: project, id: 'page/path', text: '*Markdown* text' + post :preview_markdown, params: { namespace_id: project.namespace, project_id: project, id: 'page/path', text: '*Markdown* text' } expect(JSON.parse(response.body).keys).to match_array(%w(body references)) end end describe 'GET #edit' do - subject { get(:edit, namespace_id: project.namespace, project_id: project, id: wiki_title) } + subject { get(:edit, params: { namespace_id: project.namespace, project_id: project, id: wiki_title }) } context 'when page content encoding is invalid' do it 'redirects to show' do @@ -178,10 +123,12 @@ describe Projects::WikisController do let(:new_content) { 'New content' } subject do patch(:update, - namespace_id: project.namespace, - project_id: project, - id: wiki_title, - wiki: { title: new_title, content: new_content }) + params: { + namespace_id: project.namespace, + project_id: project, + id: wiki_title, + wiki: { title: new_title, content: new_content } + }) end context 'when page content encoding is invalid' do diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 576191a5788..4747d837273 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -22,7 +22,7 @@ describe ProjectsController do it 'renders the template' do group.add_owner(user) - get :new, namespace_id: group.id + get :new, params: { namespace_id: group.id } expect(response).to have_gitlab_http_status(200) expect(response).to render_template('new') @@ -31,7 +31,7 @@ describe ProjectsController do context 'when user does not have access to the namespace' do it 'responds with status 404' do - get :new, namespace_id: group.id + get :new, params: { namespace_id: group.id } expect(response).to have_gitlab_http_status(404) expect(response).not_to render_template('new') @@ -71,7 +71,7 @@ describe ProjectsController do let(:private_project) { create(:project, :private) } it "does not initialize notification setting" do - get :show, namespace_id: private_project.namespace, id: private_project + get :show, params: { namespace_id: private_project.namespace, id: private_project } expect(assigns(:notification_setting)).to be_nil end end @@ -79,7 +79,7 @@ describe ProjectsController do context "user has access to project" do context "and does not have notification setting" do it "initializes notification as disabled" do - get :show, namespace_id: public_project.namespace, id: public_project + get :show, params: { namespace_id: public_project.namespace, id: public_project } expect(assigns(:notification_setting).level).to eq("global") end end @@ -92,7 +92,7 @@ describe ProjectsController do end it "shows current notification setting" do - get :show, namespace_id: public_project.namespace, id: public_project + get :show, params: { namespace_id: public_project.namespace, id: public_project } expect(assigns(:notification_setting).level).to eq("watch") end end @@ -107,7 +107,7 @@ describe ProjectsController do end it 'shows wiki homepage' do - get :show, namespace_id: project.namespace, id: project + get :show, params: { namespace_id: project.namespace, id: project } expect(response).to render_template('projects/_wiki') end @@ -116,7 +116,7 @@ describe ProjectsController do project.project_feature.update_attribute(:wiki_access_level, ProjectFeature::DISABLED) create(:issue, project: project) - get :show, namespace_id: project.namespace, id: project + get :show, params: { namespace_id: project.namespace, id: project } expect(response).to render_template('projects/issues/_issues') expect(assigns(:issuable_meta_data)).not_to be_nil @@ -126,7 +126,7 @@ describe ProjectsController do project.project_feature.update_attribute(:wiki_access_level, ProjectFeature::DISABLED) project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED) - get :show, namespace_id: project.namespace, id: project + get :show, params: { namespace_id: project.namespace, id: project } expect(response).to render_template("projects/_customize_workflow") end @@ -134,7 +134,7 @@ describe ProjectsController do it 'shows activity if enabled by user' do user.update_attribute(:project_view, 'activity') - get :show, namespace_id: project.namespace, id: project + get :show, params: { namespace_id: project.namespace, id: project } expect(response).to render_template("projects/_activity") end @@ -150,7 +150,7 @@ describe ProjectsController do end it 'renders a 503' do - get :show, namespace_id: project.namespace, id: project + get :show, params: { namespace_id: project.namespace, id: project } expect(response).to have_gitlab_http_status(503) end @@ -168,7 +168,7 @@ describe ProjectsController do before do user.update(project_view: project_view) - get :show, namespace_id: empty_project.namespace, id: empty_project + get :show, params: { namespace_id: empty_project.namespace, id: empty_project } end it "renders the empty project view" do @@ -190,7 +190,7 @@ describe ProjectsController do before do user.update(project_view: project_view) - get :show, namespace_id: empty_project.namespace, id: empty_project + get :show, params: { namespace_id: empty_project.namespace, id: empty_project } end it "renders the empty project view" do @@ -211,7 +211,7 @@ describe ProjectsController do allow(controller).to receive(:current_user).and_return(user) allow(user).to receive(:project_view).and_return('activity') - get :show, namespace_id: public_project.namespace, id: public_project + get :show, params: { namespace_id: public_project.namespace, id: public_project } expect(response).to render_template('_activity') end @@ -219,7 +219,7 @@ describe ProjectsController do allow(controller).to receive(:current_user).and_return(user) allow(user).to receive(:project_view).and_return('files') - get :show, namespace_id: public_project.namespace, id: public_project + get :show, params: { namespace_id: public_project.namespace, id: public_project } expect(response).to render_template('_files') end @@ -227,7 +227,7 @@ describe ProjectsController do allow(controller).to receive(:current_user).and_return(user) allow(user).to receive(:project_view).and_return('readme') - get :show, namespace_id: public_project.namespace, id: public_project + get :show, params: { namespace_id: public_project.namespace, id: public_project } expect(response).to render_template('_readme') end end @@ -245,7 +245,7 @@ describe ProjectsController do project = create(:project, pending_delete: true) sign_in(user) - get :show, namespace_id: project.namespace, id: project + get :show, params: { namespace_id: project.namespace, id: project } expect(response.status).to eq 404 end @@ -255,7 +255,7 @@ describe ProjectsController do it 'redirects to project page (format.html)' do project = create(:project, :public) - get :show, namespace_id: project.namespace, id: project, format: :git + get :show, params: { namespace_id: project.namespace, id: project }, format: :git expect(response).to have_gitlab_http_status(302) expect(response).to redirect_to(namespace_project_path) @@ -278,7 +278,7 @@ describe ProjectsController do it 'does not increase the number of queries when the project is forked' do expected_query = /#{public_project.fork_network.find_forks_in(other_user.namespace).to_sql}/ - expect { get(:show, namespace_id: public_project.namespace, id: public_project) } + expect { get(:show, params: { namespace_id: public_project.namespace, id: public_project }) } .not_to exceed_query_limit(2).for_query(expected_query) end end @@ -290,8 +290,10 @@ describe ProjectsController do project.add_maintainer(user) get :edit, - namespace_id: project.namespace.path, - id: project.path + params: { + namespace_id: project.namespace.path, + id: project.path + } expect(assigns(:badge_api_endpoint)).not_to be_nil end @@ -355,9 +357,11 @@ describe ProjectsController do } put :update, - namespace_id: project.namespace, - id: project.id, - project: params + params: { + namespace_id: project.namespace, + id: project.id, + project: params + } expect(response).to have_gitlab_http_status(302) params.each do |param, value| @@ -367,9 +371,11 @@ describe ProjectsController do def update_project(**parameters) put :update, - namespace_id: project.namespace.path, - id: project.path, - project: parameters + params: { + namespace_id: project.namespace.path, + id: project.path, + project: parameters + } end end @@ -397,9 +403,11 @@ describe ProjectsController do sign_in(admin) put :transfer, - namespace_id: project.namespace.path, - new_namespace_id: new_namespace.id, - id: project.path, + params: { + namespace_id: project.namespace.path, + new_namespace_id: new_namespace.id, + id: project.path + }, format: :js project.reload @@ -416,9 +424,11 @@ describe ProjectsController do old_namespace = project.namespace put :transfer, - namespace_id: old_namespace.path, - new_namespace_id: nil, - id: project.path, + params: { + namespace_id: old_namespace.path, + new_namespace_id: nil, + id: project.path + }, format: :js project.reload @@ -438,7 +448,7 @@ describe ProjectsController do sign_in(admin) orig_id = project.id - delete :destroy, namespace_id: project.namespace, id: project + delete :destroy, params: { namespace_id: project.namespace, id: project } expect { Project.find(orig_id) }.to raise_error(ActiveRecord::RecordNotFound) expect(response).to have_gitlab_http_status(302) @@ -458,7 +468,7 @@ describe ProjectsController do project.merge_requests << merge_request sign_in(admin) - delete :destroy, namespace_id: forked_project.namespace, id: forked_project + delete :destroy, params: { namespace_id: forked_project.namespace, id: forked_project } expect(merge_request.reload.state).to eq('closed') end @@ -468,9 +478,11 @@ describe ProjectsController do describe 'PUT #new_issuable_address for issue' do subject do put :new_issuable_address, - namespace_id: project.namespace, - id: project, - issuable_type: 'issue' + params: { + namespace_id: project.namespace, + id: project, + issuable_type: 'issue' + } user.reload end @@ -496,9 +508,11 @@ describe ProjectsController do describe 'PUT #new_issuable_address for merge request' do subject do put :new_issuable_address, - namespace_id: project.namespace, - id: project, - issuable_type: 'merge_request' + params: { + namespace_id: project.namespace, + id: project, + issuable_type: 'merge_request' + } user.reload end @@ -526,23 +540,31 @@ describe ProjectsController do sign_in(user) expect(user.starred?(public_project)).to be_falsey post(:toggle_star, - namespace_id: public_project.namespace, - id: public_project) + params: { + namespace_id: public_project.namespace, + id: public_project + }) expect(user.starred?(public_project)).to be_truthy post(:toggle_star, - namespace_id: public_project.namespace, - id: public_project) + params: { + namespace_id: public_project.namespace, + id: public_project + }) expect(user.starred?(public_project)).to be_falsey end it "does nothing if user is not signed in" do post(:toggle_star, - namespace_id: project.namespace, - id: public_project) + params: { + namespace_id: project.namespace, + id: public_project + }) expect(user.starred?(public_project)).to be_falsey post(:toggle_star, - namespace_id: project.namespace, - id: public_project) + params: { + namespace_id: project.namespace, + id: public_project + }) expect(user.starred?(public_project)).to be_falsey end end @@ -558,8 +580,11 @@ describe ProjectsController do it 'removes fork from project' do delete(:remove_fork, - namespace_id: forked_project.namespace.to_param, - id: forked_project.to_param, format: :js) + params: { + namespace_id: forked_project.namespace.to_param, + id: forked_project.to_param + }, + format: :js) expect(forked_project.reload.forked?).to be_falsey expect(flash[:notice]).to eq('The fork relationship has been removed.') @@ -572,8 +597,11 @@ describe ProjectsController do it 'does nothing if project was not forked' do delete(:remove_fork, - namespace_id: unforked_project.namespace, - id: unforked_project, format: :js) + params: { + namespace_id: unforked_project.namespace, + id: unforked_project + }, + format: :js) expect(flash[:notice]).to be_nil expect(response).to render_template(:remove_fork) @@ -583,17 +611,20 @@ describe ProjectsController do it "does nothing if user is not signed in" do delete(:remove_fork, - namespace_id: project.namespace, - id: project, format: :js) + params: { + namespace_id: project.namespace, + id: project + }, + format: :js) expect(response).to have_gitlab_http_status(401) end end describe "GET refs" do - let(:public_project) { create(:project, :public, :repository) } + let(:project) { create(:project, :public, :repository) } it 'gets a list of branches and tags' do - get :refs, namespace_id: public_project.namespace, id: public_project, sort: 'updated_desc' + get :refs, params: { namespace_id: project.namespace, id: project, sort: 'updated_desc' } parsed_body = JSON.parse(response.body) expect(parsed_body['Branches']).to include('master') @@ -603,7 +634,7 @@ describe ProjectsController do end it "gets a list of branches, tags and commits" do - get :refs, namespace_id: public_project.namespace, id: public_project, ref: "123456" + get :refs, params: { namespace_id: project.namespace, id: project, ref: "123456" } parsed_body = JSON.parse(response.body) expect(parsed_body["Branches"]).to include("master") @@ -618,7 +649,7 @@ describe ProjectsController do end it "gets a list of branches, tags and commits" do - get :refs, namespace_id: public_project.namespace, id: public_project, ref: "123456" + get :refs, params: { namespace_id: project.namespace, id: project, ref: "123456" } parsed_body = JSON.parse(response.body) expect(parsed_body["Branches"]).to include("master") @@ -626,6 +657,22 @@ describe ProjectsController do expect(parsed_body["Commits"]).to include("123456") end end + + context 'when private project' do + let(:project) { create(:project, :repository) } + + context 'as a guest' do + it 'renders forbidden' do + user = create(:user) + project.add_guest(user) + + sign_in(user) + get :refs, namespace_id: project.namespace, id: project + + expect(response).to have_gitlab_http_status(404) + end + end + end end describe 'POST #preview_markdown' do @@ -634,7 +681,7 @@ describe ProjectsController do end it 'renders json in a correct format' do - post :preview_markdown, namespace_id: public_project.namespace, id: public_project, text: '*Markdown* text' + post :preview_markdown, params: { namespace_id: public_project.namespace, id: public_project, text: '*Markdown* text' } expect(JSON.parse(response.body).keys).to match_array(%w(body references)) end @@ -644,9 +691,11 @@ describe ProjectsController do let(:merge_request) { create(:merge_request, :closed, target_project: public_project) } it 'renders JSON body with state filter for issues' do - post :preview_markdown, namespace_id: public_project.namespace, - id: public_project, - text: issue.to_reference + post :preview_markdown, params: { + namespace_id: public_project.namespace, + id: public_project, + text: issue.to_reference + } json_response = JSON.parse(response.body) @@ -654,9 +703,11 @@ describe ProjectsController do end it 'renders JSON body with state filter for MRs' do - post :preview_markdown, namespace_id: public_project.namespace, - id: public_project, - text: merge_request.to_reference + post :preview_markdown, params: { + namespace_id: public_project.namespace, + id: public_project, + text: merge_request.to_reference + } json_response = JSON.parse(response.body) @@ -674,7 +725,7 @@ describe ProjectsController do context 'when requesting the canonical path' do context "with exactly matching casing" do it "loads the project" do - get :show, namespace_id: public_project.namespace, id: public_project + get :show, params: { namespace_id: public_project.namespace, id: public_project } expect(assigns(:project)).to eq(public_project) expect(response).to have_gitlab_http_status(200) @@ -683,7 +734,7 @@ describe ProjectsController do context "with different casing" do it "redirects to the normalized path" do - get :show, namespace_id: public_project.namespace, id: public_project.path.upcase + get :show, params: { namespace_id: public_project.namespace, id: public_project.path.upcase } expect(assigns(:project)).to eq(public_project) expect(response).to redirect_to("/#{public_project.full_path}") @@ -696,14 +747,14 @@ describe ProjectsController do let!(:redirect_route) { public_project.redirect_routes.create!(path: "foo/bar") } it 'redirects to the canonical path' do - get :show, namespace_id: 'foo', id: 'bar' + get :show, params: { namespace_id: 'foo', id: 'bar' } expect(response).to redirect_to(public_project) expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, public_project)) end it 'redirects to the canonical path (testing non-show action)' do - get :refs, namespace_id: 'foo', id: 'bar' + get :refs, params: { namespace_id: 'foo', id: 'bar' } expect(response).to redirect_to(refs_project_path(public_project)) expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, public_project)) @@ -714,13 +765,13 @@ describe ProjectsController do context 'for a POST request' do context 'when requesting the canonical path with different casing' do it 'does not 404' do - post :toggle_star, namespace_id: public_project.namespace, id: public_project.path.upcase + post :toggle_star, params: { namespace_id: public_project.namespace, id: public_project.path.upcase } expect(response).not_to have_gitlab_http_status(404) end it 'does not redirect to the correct casing' do - post :toggle_star, namespace_id: public_project.namespace, id: public_project.path.upcase + post :toggle_star, params: { namespace_id: public_project.namespace, id: public_project.path.upcase } expect(response).not_to have_gitlab_http_status(301) end @@ -730,7 +781,7 @@ describe ProjectsController do let!(:redirect_route) { public_project.redirect_routes.create!(path: "foo/bar") } it 'returns not found' do - post :toggle_star, namespace_id: 'foo', id: 'bar' + post :toggle_star, params: { namespace_id: 'foo', id: 'bar' } expect(response).to have_gitlab_http_status(404) end @@ -744,13 +795,13 @@ describe ProjectsController do context 'when requesting the canonical path with different casing' do it 'does not 404' do - delete :destroy, namespace_id: project.namespace, id: project.path.upcase + delete :destroy, params: { namespace_id: project.namespace, id: project.path.upcase } expect(response).not_to have_gitlab_http_status(404) end it 'does not redirect to the correct casing' do - delete :destroy, namespace_id: project.namespace, id: project.path.upcase + delete :destroy, params: { namespace_id: project.namespace, id: project.path.upcase } expect(response).not_to have_gitlab_http_status(301) end @@ -760,7 +811,7 @@ describe ProjectsController do let!(:redirect_route) { project.redirect_routes.create!(path: "foo/bar") } it 'returns not found' do - delete :destroy, namespace_id: 'foo', id: 'bar' + delete :destroy, params: { namespace_id: 'foo', id: 'bar' } expect(response).to have_gitlab_http_status(404) end @@ -777,7 +828,7 @@ describe ProjectsController do context 'when project export is enabled' do it 'returns 302' do - get :export, namespace_id: project.namespace, id: project + get :export, params: { namespace_id: project.namespace, id: project } expect(response).to have_gitlab_http_status(302) end @@ -789,7 +840,7 @@ describe ProjectsController do end it 'returns 404' do - get :export, namespace_id: project.namespace, id: project + get :export, params: { namespace_id: project.namespace, id: project } expect(response).to have_gitlab_http_status(404) end @@ -806,7 +857,7 @@ describe ProjectsController do context 'object storage enabled' do context 'when project export is enabled' do it 'returns 302' do - get :download_export, namespace_id: project.namespace, id: project + get :download_export, params: { namespace_id: project.namespace, id: project } expect(response).to have_gitlab_http_status(302) end @@ -818,7 +869,7 @@ describe ProjectsController do end it 'returns 404' do - get :download_export, namespace_id: project.namespace, id: project + get :download_export, params: { namespace_id: project.namespace, id: project } expect(response).to have_gitlab_http_status(404) end @@ -835,7 +886,7 @@ describe ProjectsController do context 'when project export is enabled' do it 'returns 302' do - post :remove_export, namespace_id: project.namespace, id: project + post :remove_export, params: { namespace_id: project.namespace, id: project } expect(response).to have_gitlab_http_status(302) end @@ -847,7 +898,7 @@ describe ProjectsController do end it 'returns 404' do - post :remove_export, namespace_id: project.namespace, id: project + post :remove_export, params: { namespace_id: project.namespace, id: project } expect(response).to have_gitlab_http_status(404) end @@ -863,7 +914,7 @@ describe ProjectsController do context 'when project export is enabled' do it 'returns 302' do - post :generate_new_export, namespace_id: project.namespace, id: project + post :generate_new_export, params: { namespace_id: project.namespace, id: project } expect(response).to have_gitlab_http_status(302) end @@ -875,7 +926,7 @@ describe ProjectsController do end it 'returns 404' do - post :generate_new_export, namespace_id: project.namespace, id: project + post :generate_new_export, params: { namespace_id: project.namespace, id: project } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index d334a2ff566..fd151e8a298 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -17,7 +17,7 @@ describe RegistrationsController do it 'signs the user in' do allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(false) - expect { post(:create, user_params) }.not_to change { ActionMailer::Base.deliveries.size } + expect { post(:create, params: user_params) }.not_to change { ActionMailer::Base.deliveries.size } expect(subject.current_user).not_to be_nil end end @@ -26,7 +26,7 @@ describe RegistrationsController do it 'does not authenticate user and sends confirmation email' do allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(true) - post(:create, user_params) + post(:create, params: user_params) expect(ActionMailer::Base.deliveries.last.to.first).to eq(user_params[:user][:email]) expect(subject.current_user).to be_nil @@ -37,7 +37,7 @@ describe RegistrationsController do it 'redirects to sign_in' do allow_any_instance_of(ApplicationSetting).to receive(:signup_enabled?).and_return(false) - expect { post(:create, user_params) }.not_to change(User, :count) + expect { post(:create, params: user_params) }.not_to change(User, :count) expect(response).to redirect_to(new_user_session_path) end end @@ -52,7 +52,7 @@ describe RegistrationsController do # Without this, `verify_recaptcha` arbitrarily returns true in test env Recaptcha.configuration.skip_verify_env.delete('test') - post(:create, user_params) + post(:create, params: user_params) expect(response).to render_template(:new) expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.' @@ -64,7 +64,7 @@ describe RegistrationsController do Recaptcha.configuration.skip_verify_env << 'test' end - post(:create, user_params) + post(:create, params: user_params) expect(flash[:notice]).to include 'Welcome! You have signed up successfully.' end @@ -76,13 +76,13 @@ describe RegistrationsController do end it 'redirects back with a notice when the checkbox was not checked' do - post :create, user_params + post :create, params: user_params expect(flash[:alert]).to match /you must accept our terms/i end it 'creates the user with agreement when terms are accepted' do - post :create, user_params.merge(terms_opt_in: '1') + post :create, params: user_params.merge(terms_opt_in: '1') expect(subject.current_user).to be_present expect(subject.current_user.terms_accepted?).to be(true) @@ -125,13 +125,13 @@ describe RegistrationsController do end it 'fails if password confirmation is wrong' do - post :destroy, password: 'wrong password' + post :destroy, params: { password: 'wrong password' } expect_password_failure end it 'succeeds if password is confirmed' do - post :destroy, password: '12345678' + post :destroy, params: { password: '12345678' } expect_success end @@ -150,13 +150,13 @@ describe RegistrationsController do end it 'fails if username confirmation is wrong' do - post :destroy, username: 'wrong username' + post :destroy, params: { username: 'wrong username' } expect_username_failure end it 'succeeds if username is confirmed' do - post :destroy, username: user.username + post :destroy, params: { username: user.username } expect_success end diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index 416a09e1684..c9b53336fd1 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -11,7 +11,7 @@ describe SearchController do project = create(:project, :public) note = create(:note_on_issue, project: project) - get :show, project_id: project.id, scope: 'notes', search: note.note + get :show, params: { project_id: project.id, scope: 'notes', search: note.note } expect(assigns[:search_objects].first).to eq note end @@ -30,13 +30,13 @@ describe SearchController do end it 'still blocks searches without a project_id' do - get :show, search: 'hello' + get :show, params: { search: 'hello' } expect(response).to have_gitlab_http_status(403) end it 'allows searches with a project_id' do - get :show, search: 'hello', project_id: create(:project, :public).id + get :show, params: { search: 'hello', project_id: create(:project, :public).id } expect(response).to have_gitlab_http_status(200) end @@ -52,7 +52,7 @@ describe SearchController do project = create(:project, :public, :issues_private) note = create(:note_on_issue, project: project) - get :show, project_id: project.id, scope: 'notes', search: note.note + get :show, params: { project_id: project.id, scope: 'notes', search: note.note } expect(assigns[:search_objects].count).to eq(0) end @@ -62,7 +62,7 @@ describe SearchController do project = create(:project, :public, :merge_requests_private) note = create(:note_on_merge_request, project: project) - get :show, project_id: project.id, scope: 'notes', search: note.note + get :show, params: { project_id: project.id, scope: 'notes', search: note.note } expect(assigns[:search_objects].count).to eq(0) end @@ -71,7 +71,7 @@ describe SearchController do project = create(:project, :public, :snippets_private) note = create(:note_on_project_snippet, project: project) - get :show, project_id: project.id, scope: 'notes', search: note.note + get :show, params: { project_id: project.id, scope: 'notes', search: note.note } expect(assigns[:search_objects].count).to eq(0) end diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb index 54a9af92f07..75c91dd8607 100644 --- a/spec/controllers/sent_notifications_controller_spec.rb +++ b/spec/controllers/sent_notifications_controller_spec.rb @@ -15,7 +15,7 @@ describe SentNotificationsController do context 'when the user is not logged in' do context 'when the force param is passed' do before do - get(:unsubscribe, id: sent_notification.reply_key, force: true) + get(:unsubscribe, params: { id: sent_notification.reply_key, force: true }) end it 'unsubscribes the user' do @@ -33,7 +33,7 @@ describe SentNotificationsController do context 'when the force param is not passed' do before do - get(:unsubscribe, id: sent_notification.reply_key) + get(:unsubscribe, params: { id: sent_notification.reply_key }) end it 'does not unsubscribe the user' do @@ -57,7 +57,7 @@ describe SentNotificationsController do context 'when the ID passed does not exist' do before do - get(:unsubscribe, id: sent_notification.reply_key.reverse) + get(:unsubscribe, params: { id: sent_notification.reply_key.reverse }) end it 'does not unsubscribe the user' do @@ -75,7 +75,7 @@ describe SentNotificationsController do context 'when the force param is passed' do before do - get(:unsubscribe, id: sent_notification.reply_key, force: true) + get(:unsubscribe, params: { id: sent_notification.reply_key, force: true }) end it 'unsubscribes the user' do @@ -101,7 +101,7 @@ describe SentNotificationsController do let(:sent_notification) { create(:sent_notification, project: project, noteable: merge_request, recipient: user) } before do - get(:unsubscribe, id: sent_notification.reply_key) + get(:unsubscribe, params: { id: sent_notification.reply_key }) end it 'unsubscribes the user' do diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index c691b3f478b..ea7242c1aa8 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -26,7 +26,7 @@ describe SessionsController do context 'and auto_sign_in=false param is passed' do it 'responds with 200' do - get(:new, auto_sign_in: 'false') + get(:new, params: { auto_sign_in: 'false' }) expect(response).to have_gitlab_http_status(200) end @@ -42,7 +42,7 @@ describe SessionsController do context 'when using standard authentications' do context 'invalid password' do it 'does not authenticate user' do - post(:create, user: { login: 'invalid', password: 'invalid' }) + post(:create, params: { user: { login: 'invalid', password: 'invalid' } }) expect(response) .to set_flash.now[:alert].to /Invalid Login or password/ @@ -54,19 +54,19 @@ describe SessionsController do let(:user_params) { { login: user.username, password: user.password } } it 'authenticates user correctly' do - post(:create, user: user_params) + post(:create, params: { user: user_params }) expect(subject.current_user). to eq user end it 'creates an audit log record' do - expect { post(:create, user: user_params) }.to change { SecurityEvent.count }.by(1) + expect { post(:create, params: { user: user_params }) }.to change { SecurityEvent.count }.by(1) expect(SecurityEvent.last.details[:with]).to eq('standard') end include_examples 'user login request with unique ip limit', 302 do def request - post(:create, user: user_params) + post(:create, params: { user: user_params }) expect(subject.current_user).to eq user subject.sign_out user end @@ -74,7 +74,7 @@ describe SessionsController do it 'updates the user activity' do expect do - post(:create, user: user_params) + post(:create, params: { user: user_params }) end.to change { user.reload.last_activity_on }.to(Date.today) end end @@ -98,7 +98,7 @@ describe SessionsController do .with(:failed_login_captcha_total, anything) .and_return(counter) - post(:create, user: user_params) + post(:create, params: { user: user_params }) expect(response).to render_template(:new) expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.' @@ -116,7 +116,7 @@ describe SessionsController do .and_return(counter) expect(Gitlab::Metrics).to receive(:counter).and_call_original - post(:create, user: user_params) + post(:create, params: { user: user_params }) expect(subject.current_user).to eq user end @@ -127,7 +127,7 @@ describe SessionsController do let(:user) { create(:user, :two_factor) } def authenticate_2fa(user_params) - post(:create, { user: user_params }, { otp_user_id: user.id }) + post(:create, params: { user: user_params }, session: { otp_user_id: user.id }) end context 'remember_me field' do @@ -233,7 +233,7 @@ describe SessionsController do end it 'keeps the user locked on future login attempts' do - post(:create, user: { login: user.username, password: user.password }) + post(:create, params: { user: { login: user.username, password: user.password } }) expect(response) .to set_flash.now[:alert].to /Invalid Login or password/ @@ -265,7 +265,7 @@ describe SessionsController do let(:user) { create(:user, :two_factor) } def authenticate_2fa_u2f(user_params) - post(:create, { user: user_params }, { otp_user_id: user.id }) + post(:create, params: { user: user_params }, session: { otp_user_id: user.id }) end context 'remember_me field' do @@ -309,7 +309,7 @@ describe SessionsController do search_path = "/search?search=seed_project" request.headers[:HTTP_REFERER] = "http://#{host}#{search_path}" - get(:new, redirect_to_referer: :yes) + get(:new, params: { redirect_to_referer: :yes }) expect(controller.stored_location_for(:redirect)).to eq(search_path) end diff --git a/spec/controllers/snippets/notes_controller_spec.rb b/spec/controllers/snippets/notes_controller_spec.rb index e6148ea1734..6efbd1f6c71 100644 --- a/spec/controllers/snippets/notes_controller_spec.rb +++ b/spec/controllers/snippets/notes_controller_spec.rb @@ -16,7 +16,7 @@ describe Snippets::NotesController do before do note_on_public - get :index, { snippet_id: public_snippet } + get :index, params: { snippet_id: public_snippet } end it "returns status 200" do @@ -35,7 +35,7 @@ describe Snippets::NotesController do context 'when user not logged in' do it "returns status 404" do - get :index, { snippet_id: internal_snippet } + get :index, params: { snippet_id: internal_snippet } expect(response).to have_gitlab_http_status(404) end @@ -47,7 +47,7 @@ describe Snippets::NotesController do end it "returns status 200" do - get :index, { snippet_id: internal_snippet } + get :index, params: { snippet_id: internal_snippet } expect(response).to have_gitlab_http_status(200) end @@ -61,7 +61,7 @@ describe Snippets::NotesController do context 'when user not logged in' do it "returns status 404" do - get :index, { snippet_id: private_snippet } + get :index, params: { snippet_id: private_snippet } expect(response).to have_gitlab_http_status(404) end @@ -73,7 +73,7 @@ describe Snippets::NotesController do end it "returns status 404" do - get :index, { snippet_id: private_snippet } + get :index, params: { snippet_id: private_snippet } expect(response).to have_gitlab_http_status(404) end @@ -87,13 +87,13 @@ describe Snippets::NotesController do end it "returns status 200" do - get :index, { snippet_id: private_snippet } + get :index, params: { snippet_id: private_snippet } expect(response).to have_gitlab_http_status(200) end it "returns 1 note" do - get :index, { snippet_id: private_snippet } + get :index, params: { snippet_id: private_snippet } expect(JSON.parse(response.body)['notes'].count).to eq(1) end @@ -110,7 +110,7 @@ describe Snippets::NotesController do end it "does not return any note" do - get :index, { snippet_id: public_snippet } + get :index, params: { snippet_id: public_snippet } expect(JSON.parse(response.body)['notes'].count).to eq(0) end @@ -132,13 +132,13 @@ describe Snippets::NotesController do end it "returns status 200" do - delete :destroy, request_params + delete :destroy, params: request_params expect(response).to have_gitlab_http_status(200) end it "deletes the note" do - expect { delete :destroy, request_params }.to change { Note.count }.from(1).to(0) + expect { delete :destroy, params: request_params }.to change { Note.count }.from(1).to(0) end context 'system note' do @@ -147,7 +147,7 @@ describe Snippets::NotesController do end it "does not delete the note" do - expect { delete :destroy, request_params }.not_to change { Note.count } + expect { delete :destroy, params: request_params }.not_to change { Note.count } end end end @@ -160,13 +160,13 @@ describe Snippets::NotesController do end it "returns status 404" do - delete :destroy, request_params + delete :destroy, params: request_params expect(response).to have_gitlab_http_status(404) end it "does not update the note" do - expect { delete :destroy, request_params }.not_to change { Note.count } + expect { delete :destroy, params: request_params }.not_to change { Note.count } end end end @@ -177,7 +177,7 @@ describe Snippets::NotesController do sign_in(user) end - subject { post(:toggle_award_emoji, snippet_id: public_snippet, id: note.id, name: "thumbsup") } + subject { post(:toggle_award_emoji, params: { snippet_id: public_snippet, id: note.id, name: "thumbsup" }) } it "toggles the award emoji" do expect { subject }.to change { note.award_emoji.count }.by(1) diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb index 957bab638b1..d762531da7e 100644 --- a/spec/controllers/snippets_controller_spec.rb +++ b/spec/controllers/snippets_controller_spec.rb @@ -8,7 +8,7 @@ describe SnippetsController do context 'when username parameter is present' do it 'renders snippets of a user when username is present' do - get :index, username: user.username + get :index, params: { username: user.username } expect(response).to render_template(:index) end @@ -67,7 +67,7 @@ describe SnippetsController do let(:other_personal_snippet) { create(:personal_snippet, :private, author: other_author) } it 'responds with status 404' do - get :show, id: other_personal_snippet.to_param + get :show, params: { id: other_personal_snippet.to_param } expect(response).to have_gitlab_http_status(404) end @@ -75,17 +75,23 @@ describe SnippetsController do context 'when signed in user is the author' do it 'renders the snippet' do - get :show, id: personal_snippet.to_param + get :show, params: { id: personal_snippet.to_param } expect(assigns(:snippet)).to eq(personal_snippet) expect(response).to have_gitlab_http_status(200) end + + it 'responds with status 404 when embeddable content is requested' do + get :show, id: personal_snippet.to_param, format: :js + + expect(response).to have_gitlab_http_status(404) + end end end context 'when not signed in' do it 'redirects to the sign in page' do - get :show, id: personal_snippet.to_param + get :show, params: { id: personal_snippet.to_param } expect(response).to redirect_to(new_user_session_path) end @@ -101,16 +107,22 @@ describe SnippetsController do end it 'renders the snippet' do - get :show, id: personal_snippet.to_param + get :show, params: { id: personal_snippet.to_param } expect(assigns(:snippet)).to eq(personal_snippet) expect(response).to have_gitlab_http_status(200) end + + it 'responds with status 404 when embeddable content is requested' do + get :show, id: personal_snippet.to_param, format: :js + + expect(response).to have_gitlab_http_status(404) + end end context 'when not signed in' do it 'redirects to the sign in page' do - get :show, id: personal_snippet.to_param + get :show, params: { id: personal_snippet.to_param } expect(response).to redirect_to(new_user_session_path) end @@ -126,7 +138,14 @@ describe SnippetsController do end it 'renders the snippet' do - get :show, id: personal_snippet.to_param + get :show, params: { id: personal_snippet.to_param } + + expect(assigns(:snippet)).to eq(personal_snippet) + expect(response).to have_gitlab_http_status(200) + end + + it 'responds with status 200 when embeddable content is requested' do + get :show, id: personal_snippet.to_param, format: :js expect(assigns(:snippet)).to eq(personal_snippet) expect(response).to have_gitlab_http_status(200) @@ -135,7 +154,7 @@ describe SnippetsController do context 'when not signed in' do it 'renders the snippet' do - get :show, id: personal_snippet.to_param + get :show, params: { id: personal_snippet.to_param } expect(assigns(:snippet)).to eq(personal_snippet) expect(response).to have_gitlab_http_status(200) @@ -150,7 +169,7 @@ describe SnippetsController do end it 'responds with status 404' do - get :show, id: 'doesntexist' + get :show, params: { id: 'doesntexist' } expect(response).to have_gitlab_http_status(404) end @@ -158,7 +177,7 @@ describe SnippetsController do context 'when not signed in' do it 'responds with status 404' do - get :show, id: 'doesntexist' + get :show, params: { id: 'doesntexist' } expect(response).to redirect_to(new_user_session_path) end @@ -170,7 +189,7 @@ describe SnippetsController do def create_snippet(snippet_params = {}, additional_params = {}) sign_in(user) - post :create, { + post :create, params: { personal_snippet: { title: 'Title', content: 'Content', description: 'Description' }.merge(snippet_params) }.merge(additional_params) @@ -279,7 +298,7 @@ describe SnippetsController do def update_snippet(snippet_params = {}, additional_params = {}) sign_in(user) - put :update, { + put :update, params: { id: snippet.id, personal_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params) }.merge(additional_params) @@ -406,7 +425,7 @@ describe SnippetsController do create(:user_agent_detail, subject: snippet) sign_in(admin) - post :mark_as_spam, id: snippet.id + post :mark_as_spam, params: { id: snippet.id } end it 'updates the snippet' do @@ -430,18 +449,15 @@ describe SnippetsController do let(:other_personal_snippet) { create(:personal_snippet, :private, author: other_author) } it 'responds with status 404' do - get :raw, id: other_personal_snippet.to_param + get :raw, params: { id: other_personal_snippet.to_param } expect(response).to have_gitlab_http_status(404) end end context 'when signed in user is the author' do - let(:flag_value) { false } - before do - stub_feature_flags(workhorse_set_content_type: flag_value) - get :raw, id: personal_snippet.to_param + get :raw, params: { id: personal_snippet.to_param } end it 'responds with status 200' do @@ -455,29 +471,16 @@ describe SnippetsController do expect(response.header['Content-Disposition']).to match(/inline/) end - context 'when feature flag workhorse_set_content_type is' do - context 'enabled' do - let(:flag_value) { true } - - it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do - expect(response).to have_gitlab_http_status(200) - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - end - end - - context 'disabled' do - it "does not set #{Gitlab::Workhorse::DETECT_HEADER} header" do - expect(response).to have_gitlab_http_status(200) - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to be nil - end - end + it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do + expect(response).to have_gitlab_http_status(200) + expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" end end end context 'when not signed in' do it 'redirects to the sign in page' do - get :raw, id: personal_snippet.to_param + get :raw, params: { id: personal_snippet.to_param } expect(response).to redirect_to(new_user_session_path) end @@ -493,7 +496,7 @@ describe SnippetsController do end it 'responds with status 200' do - get :raw, id: personal_snippet.to_param + get :raw, params: { id: personal_snippet.to_param } expect(assigns(:snippet)).to eq(personal_snippet) expect(response).to have_gitlab_http_status(200) @@ -502,7 +505,7 @@ describe SnippetsController do context 'when not signed in' do it 'redirects to the sign in page' do - get :raw, id: personal_snippet.to_param + get :raw, params: { id: personal_snippet.to_param } expect(response).to redirect_to(new_user_session_path) end @@ -518,7 +521,7 @@ describe SnippetsController do end it 'responds with status 200' do - get :raw, id: personal_snippet.to_param + get :raw, params: { id: personal_snippet.to_param } expect(assigns(:snippet)).to eq(personal_snippet) expect(response).to have_gitlab_http_status(200) @@ -530,13 +533,13 @@ describe SnippetsController do end it 'returns LF line endings by default' do - get :raw, id: personal_snippet.to_param + get :raw, params: { id: personal_snippet.to_param } expect(response.body).to eq("first line\nsecond line\nthird line") end it 'does not convert line endings when parameter present' do - get :raw, id: personal_snippet.to_param, line_ending: :raw + get :raw, params: { id: personal_snippet.to_param, line_ending: :raw } expect(response.body).to eq("first line\r\nsecond line\r\nthird line") end @@ -545,7 +548,7 @@ describe SnippetsController do context 'when not signed in' do it 'responds with status 200' do - get :raw, id: personal_snippet.to_param + get :raw, params: { id: personal_snippet.to_param } expect(assigns(:snippet)).to eq(personal_snippet) expect(response).to have_gitlab_http_status(200) @@ -560,7 +563,7 @@ describe SnippetsController do end it 'responds with status 404' do - get :raw, id: 'doesntexist' + get :raw, params: { id: 'doesntexist' } expect(response).to have_gitlab_http_status(404) end @@ -568,7 +571,7 @@ describe SnippetsController do context 'when not signed in' do it 'redirects to the sign in path' do - get :raw, id: 'doesntexist' + get :raw, params: { id: 'doesntexist' } expect(response).to redirect_to(new_user_session_path) end @@ -587,17 +590,17 @@ describe SnippetsController do describe 'POST #toggle_award_emoji' do it "toggles the award emoji" do expect do - post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + post(:toggle_award_emoji, params: { id: personal_snippet.to_param, name: "thumbsup" }) end.to change { personal_snippet.award_emoji.count }.from(0).to(1) expect(response.status).to eq(200) end it "removes the already awarded emoji" do - post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + post(:toggle_award_emoji, params: { id: personal_snippet.to_param, name: "thumbsup" }) expect do - post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + post(:toggle_award_emoji, params: { id: personal_snippet.to_param, name: "thumbsup" }) end.to change { personal_snippet.award_emoji.count }.from(1).to(0) expect(response.status).to eq(200) @@ -611,7 +614,7 @@ describe SnippetsController do it 'renders json in a correct format' do sign_in(user) - post :preview_markdown, id: snippet, text: '*Markdown* text' + post :preview_markdown, params: { id: snippet, text: '*Markdown* text' } expect(JSON.parse(response.body).keys).to match_array(%w(body references)) end diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index 6420b70a54f..19142aa1272 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -8,11 +8,7 @@ end shared_examples 'content not cached without revalidation and no-store' do it 'ensures content will not be cached without revalidation' do # Fixed in newer versions of ActivePack, it will only output a single `private`. - if Gitlab.rails5? - expect(subject['Cache-Control']).to eq('max-age=0, private, must-revalidate, no-store') - else - expect(subject['Cache-Control']).to eq('max-age=0, private, must-revalidate, private, no-store') - end + expect(subject['Cache-Control']).to eq('max-age=0, private, must-revalidate, no-store') end end @@ -27,7 +23,7 @@ describe UploadsController do context 'when a user does not have permissions to upload a file' do it "returns 401 when the user is not logged in" do - post :create, model: model, id: snippet.id, format: :json + post :create, params: { model: model, id: snippet.id }, format: :json expect(response).to have_gitlab_http_status(401) end @@ -36,7 +32,7 @@ describe UploadsController do private_snippet = create(:personal_snippet, :private) sign_in(user) - post :create, model: model, id: private_snippet.id, format: :json + post :create, params: { model: model, id: private_snippet.id }, format: :json expect(response).to have_gitlab_http_status(404) end @@ -48,25 +44,25 @@ describe UploadsController do end it "returns an error without file" do - post :create, model: model, id: snippet.id, format: :json + post :create, params: { model: model, id: snippet.id }, format: :json expect(response).to have_gitlab_http_status(422) end it "returns an error with invalid model" do - expect { post :create, model: 'invalid', id: snippet.id, format: :json } + expect { post :create, params: { model: 'invalid', id: snippet.id }, format: :json } .to raise_error(ActionController::UrlGenerationError) end it "returns 404 status when object not found" do - post :create, model: model, id: 9999, format: :json + post :create, params: { model: model, id: 9999 }, format: :json expect(response).to have_gitlab_http_status(404) end context 'with valid image' do before do - post :create, model: 'personal_snippet', id: snippet.id, file: jpg, format: :json + post :create, params: { model: 'personal_snippet', id: snippet.id, file: jpg }, format: :json end it 'returns a content with original filename, new link, and correct type.' do @@ -86,7 +82,7 @@ describe UploadsController do context 'with valid non-image file' do before do - post :create, model: 'personal_snippet', id: snippet.id, file: txt, format: :json + post :create, params: { model: 'personal_snippet', id: snippet.id, file: txt }, format: :json end it 'returns a content with original filename, new link, and correct type.' do @@ -106,7 +102,7 @@ describe UploadsController do context 'temporal with valid image' do subject do - post :create, model: 'personal_snippet', file: jpg, format: :json + post :create, params: { model: 'personal_snippet', file: jpg }, format: :json end it 'returns a content with original filename, new link, and correct type.' do @@ -123,7 +119,7 @@ describe UploadsController do context 'temporal with valid non-image file' do subject do - post :create, model: 'personal_snippet', file: txt, format: :json + post :create, params: { model: 'personal_snippet', file: txt }, format: :json end it 'returns a content with original filename, new link, and correct type.' do @@ -147,7 +143,7 @@ describe UploadsController do context 'for PNG files' do it 'returns Content-Disposition: inline' do note = create(:note, :with_attachment, project: project) - get :show, model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' + get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } expect(response['Content-Disposition']).to start_with('inline;') end @@ -156,7 +152,7 @@ describe UploadsController do context 'for SVG files' do it 'returns Content-Disposition: attachment' do note = create(:note, :with_svg_attachment, project: project) - get :show, model: 'note', mounted_as: 'attachment', id: note.id, filename: 'unsanitized.svg' + get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'unsanitized.svg' } expect(response['Content-Disposition']).to start_with('attachment;') end @@ -175,7 +171,7 @@ describe UploadsController do end it "redirects to the sign in page" do - get :show, model: "user", mounted_as: "avatar", id: user.id, filename: "dk.png" + get :show, params: { model: "user", mounted_as: "avatar", id: user.id, filename: "dk.png" } expect(response).to redirect_to(new_user_session_path) end @@ -183,14 +179,14 @@ describe UploadsController do context "when the user isn't blocked" do it "responds with status 200" do - get :show, model: "user", mounted_as: "avatar", id: user.id, filename: "dk.png" + get :show, params: { model: "user", mounted_as: "avatar", id: user.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation and no-store' do subject do - get :show, model: 'user', mounted_as: 'avatar', id: user.id, filename: 'dk.png' + get :show, params: { model: 'user', mounted_as: 'avatar', id: user.id, filename: 'dk.png' } response end @@ -200,14 +196,14 @@ describe UploadsController do context "when not signed in" do it "responds with status 200" do - get :show, model: "user", mounted_as: "avatar", id: user.id, filename: "dk.png" + get :show, params: { model: "user", mounted_as: "avatar", id: user.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation' do subject do - get :show, model: 'user', mounted_as: 'avatar', id: user.id, filename: 'dk.png' + get :show, params: { model: 'user', mounted_as: 'avatar', id: user.id, filename: 'dk.png' } response end @@ -225,14 +221,14 @@ describe UploadsController do context "when not signed in" do it "responds with status 200" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" + get :show, params: { model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation' do subject do - get :show, model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' + get :show, params: { model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' } response end @@ -245,14 +241,14 @@ describe UploadsController do end it "responds with status 200" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" + get :show, params: { model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation and no-store' do subject do - get :show, model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' + get :show, params: { model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' } response end @@ -267,7 +263,7 @@ describe UploadsController do context "when not signed in" do it "redirects to the sign in page" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" + get :show, params: { model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" } expect(response).to redirect_to(new_user_session_path) end @@ -290,7 +286,7 @@ describe UploadsController do end it "redirects to the sign in page" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" + get :show, params: { model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" } expect(response).to redirect_to(new_user_session_path) end @@ -298,14 +294,14 @@ describe UploadsController do context "when the user isn't blocked" do it "responds with status 200" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" + get :show, params: { model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation and no-store' do subject do - get :show, model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' + get :show, params: { model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' } response end @@ -315,7 +311,7 @@ describe UploadsController do context "when the user doesn't have access to the project" do it "responds with status 404" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" + get :show, params: { model: "project", mounted_as: "avatar", id: project.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(404) end @@ -330,14 +326,14 @@ describe UploadsController do context "when the group is public" do context "when not signed in" do it "responds with status 200" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" + get :show, params: { model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation' do subject do - get :show, model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' + get :show, params: { model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' } response end @@ -350,14 +346,14 @@ describe UploadsController do end it "responds with status 200" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" + get :show, params: { model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation and no-store' do subject do - get :show, model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' + get :show, params: { model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' } response end @@ -386,7 +382,7 @@ describe UploadsController do end it "redirects to the sign in page" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" + get :show, params: { model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" } expect(response).to redirect_to(new_user_session_path) end @@ -394,14 +390,14 @@ describe UploadsController do context "when the user isn't blocked" do it "responds with status 200" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" + get :show, params: { model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation and no-store' do subject do - get :show, model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' + get :show, params: { model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' } response end @@ -411,7 +407,7 @@ describe UploadsController do context "when the user doesn't have access to the project" do it "responds with status 404" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" + get :show, params: { model: "group", mounted_as: "avatar", id: group.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(404) end @@ -431,14 +427,14 @@ describe UploadsController do context "when not signed in" do it "responds with status 200" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" + get :show, params: { model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation' do subject do - get :show, model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' + get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } response end @@ -451,14 +447,14 @@ describe UploadsController do end it "responds with status 200" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" + get :show, params: { model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation and no-store' do subject do - get :show, model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' + get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } response end @@ -473,7 +469,7 @@ describe UploadsController do context "when not signed in" do it "redirects to the sign in page" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" + get :show, params: { model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" } expect(response).to redirect_to(new_user_session_path) end @@ -496,7 +492,7 @@ describe UploadsController do end it "redirects to the sign in page" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" + get :show, params: { model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" } expect(response).to redirect_to(new_user_session_path) end @@ -504,14 +500,14 @@ describe UploadsController do context "when the user isn't blocked" do it "responds with status 200" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" + get :show, params: { model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation and no-store' do subject do - get :show, model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' + get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } response end @@ -521,7 +517,7 @@ describe UploadsController do context "when the user doesn't have access to the project" do it "responds with status 404" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" + get :show, params: { model: "note", mounted_as: "attachment", id: note.id, filename: "dk.png" } expect(response).to have_gitlab_http_status(404) end @@ -536,14 +532,14 @@ describe UploadsController do context 'when not signed in' do it 'responds with status 200' do - get :show, model: 'appearance', mounted_as: 'header_logo', id: appearance.id, filename: 'dk.png' + get :show, params: { model: 'appearance', mounted_as: 'header_logo', id: appearance.id, filename: 'dk.png' } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation' do subject do - get :show, model: 'appearance', mounted_as: 'header_logo', id: appearance.id, filename: 'dk.png' + get :show, params: { model: 'appearance', mounted_as: 'header_logo', id: appearance.id, filename: 'dk.png' } response end @@ -556,14 +552,14 @@ describe UploadsController do context 'when not signed in' do it 'responds with status 200' do - get :show, model: 'appearance', mounted_as: 'logo', id: appearance.id, filename: 'dk.png' + get :show, params: { model: 'appearance', mounted_as: 'logo', id: appearance.id, filename: 'dk.png' } expect(response).to have_gitlab_http_status(200) end it_behaves_like 'content not cached without revalidation' do subject do - get :show, model: 'appearance', mounted_as: 'logo', id: appearance.id, filename: 'dk.png' + get :show, params: { model: 'appearance', mounted_as: 'logo', id: appearance.id, filename: 'dk.png' } response end @@ -577,7 +573,7 @@ describe UploadsController do context 'has a valid filename on the original file' do it 'successfully returns the file' do - get :show, model: 'appearance', mounted_as: 'favicon', id: appearance.id, filename: 'dk.png' + get :show, params: { model: 'appearance', mounted_as: 'favicon', id: appearance.id, filename: 'dk.png' } expect(response).to have_gitlab_http_status(200) expect(response.header['Content-Disposition']).to end_with 'filename="dk.png"' @@ -586,7 +582,7 @@ describe UploadsController do context 'has an invalid filename on the original file' do it 'returns a 404' do - get :show, model: 'appearance', mounted_as: 'favicon', id: appearance.id, filename: 'bogus.png' + get :show, params: { model: 'appearance', mounted_as: 'favicon', id: appearance.id, filename: 'bogus.png' } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/controllers/user_callouts_controller_spec.rb b/spec/controllers/user_callouts_controller_spec.rb index 48e2ff75cac..c71d75a3e7f 100644 --- a/spec/controllers/user_callouts_controller_spec.rb +++ b/spec/controllers/user_callouts_controller_spec.rb @@ -8,7 +8,7 @@ describe UserCalloutsController do end describe "POST #create" do - subject { post :create, feature_name: feature_name, format: :json } + subject { post :create, params: { feature_name: feature_name }, format: :json } context 'with valid feature name' do let(:feature_name) { UserCallout.feature_names.keys.first } diff --git a/spec/controllers/users/terms_controller_spec.rb b/spec/controllers/users/terms_controller_spec.rb index 0d77e91a67d..cbfd2b17864 100644 --- a/spec/controllers/users/terms_controller_spec.rb +++ b/spec/controllers/users/terms_controller_spec.rb @@ -40,7 +40,7 @@ describe Users::TermsController do describe 'POST #accept' do it 'saves that the user accepted the terms' do - post :accept, id: term.id + post :accept, params: { id: term.id } agreement = user.term_agreements.find_by(term: term) @@ -48,7 +48,7 @@ describe Users::TermsController do end it 'redirects to a path when specified' do - post :accept, id: term.id, redirect: groups_path + post :accept, params: { id: term.id, redirect: groups_path } expect(response).to redirect_to(groups_path) end @@ -56,14 +56,14 @@ describe Users::TermsController do it 'redirects to the referer when no redirect specified' do request.env["HTTP_REFERER"] = groups_url - post :accept, id: term.id + post :accept, params: { id: term.id } expect(response).to redirect_to(groups_path) end context 'redirecting to another domain' do it 'is prevented when passing a redirect param' do - post :accept, id: term.id, redirect: '//example.com/random/path' + post :accept, params: { id: term.id, redirect: '//example.com/random/path' } expect(response).to redirect_to(root_path) end @@ -71,7 +71,7 @@ describe Users::TermsController do it 'is prevented when redirecting to the referer' do request.env["HTTP_REFERER"] = 'http://example.com/and/a/path' - post :accept, id: term.id + post :accept, params: { id: term.id } expect(response).to redirect_to(root_path) end @@ -80,7 +80,7 @@ describe Users::TermsController do describe 'POST #decline' do it 'stores that the user declined the terms' do - post :decline, id: term.id + post :decline, params: { id: term.id } agreement = user.term_agreements.find_by(term: term) @@ -88,7 +88,7 @@ describe Users::TermsController do end it 'signs out the user' do - post :decline, id: term.id + post :decline, params: { id: term.id } expect(response).to redirect_to(root_path) expect(assigns(:current_user)).to be_nil diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index fe438e71e9e..27edf226ca3 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -15,7 +15,7 @@ describe UsersController do end it 'renders the show template' do - get :show, username: user.username + get :show, params: { username: user.username } expect(response).to be_success expect(response).to render_template('show') @@ -24,7 +24,7 @@ describe UsersController do describe 'when logged out' do it 'renders the show template' do - get :show, username: user.username + get :show, params: { username: user.username } expect(response).to have_gitlab_http_status(200) expect(response).to render_template('show') @@ -39,7 +39,7 @@ describe UsersController do context 'when logged out' do it 'redirects to login page' do - get :show, username: user.username + get :show, params: { username: user.username } expect(response).to redirect_to new_user_session_path end end @@ -50,7 +50,7 @@ describe UsersController do end it 'renders show' do - get :show, username: user.username + get :show, params: { username: user.username } expect(response).to have_gitlab_http_status(200) expect(response).to render_template('show') end @@ -60,7 +60,7 @@ describe UsersController do context 'when a user by that username does not exist' do context 'when logged out' do it 'redirects to login page' do - get :show, username: 'nonexistent' + get :show, params: { username: 'nonexistent' } expect(response).to redirect_to new_user_session_path end end @@ -71,7 +71,7 @@ describe UsersController do end it 'renders 404' do - get :show, username: 'nonexistent' + get :show, params: { username: 'nonexistent' } expect(response).to have_gitlab_http_status(404) end end @@ -87,7 +87,7 @@ describe UsersController do end it 'loads events' do - get :show, username: user, format: :json + get :show, params: { username: user }, format: :json expect(assigns(:events)).not_to be_empty end @@ -96,7 +96,7 @@ describe UsersController do allow(Ability).to receive(:allowed?).and_call_original expect(Ability).to receive(:allowed?).with(user, :read_cross_project) { false } - get :show, username: user, format: :json + get :show, params: { username: user }, format: :json expect(assigns(:events)).to be_empty end @@ -104,7 +104,7 @@ describe UsersController do it 'hides events if the user has a private profile' do Gitlab::DataBuilder::Push.build_sample(project, private_user) - get :show, username: private_user.username, format: :json + get :show, params: { username: private_user.username }, format: :json expect(assigns(:events)).to be_empty end @@ -125,7 +125,7 @@ describe UsersController do push_data = Gitlab::DataBuilder::Push.build_sample(project, public_user) EventCreateService.new.push(project, public_user, push_data) - get :calendar, username: public_user.username, format: :json + get :calendar, params: { username: public_user.username }, format: :json expect(response).to have_gitlab_http_status(200) end @@ -136,7 +136,7 @@ describe UsersController do push_data = Gitlab::DataBuilder::Push.build_sample(project, private_user) EventCreateService.new.push(project, private_user, push_data) - get :calendar, username: private_user.username, format: :json + get :calendar, params: { username: private_user.username }, format: :json expect(response).to have_gitlab_http_status(:not_found) end @@ -161,7 +161,7 @@ describe UsersController do end it 'includes forked projects' do - get :calendar, username: user.username + get :calendar, params: { username: user.username } expect(assigns(:contributions_calendar).projects.count).to eq(2) end end @@ -179,7 +179,7 @@ describe UsersController do end it 'assigns @calendar_date' do - get :calendar_activities, username: user.username, date: '2014-07-31' + get :calendar_activities, params: { username: user.username, date: '2014-07-31' } expect(assigns(:calendar_date)).to eq(Date.parse('2014-07-31')) end @@ -189,7 +189,7 @@ describe UsersController do push_data = Gitlab::DataBuilder::Push.build_sample(project, public_user) EventCreateService.new.push(project, public_user, push_data) - get :calendar_activities, username: public_user.username + get :calendar_activities, params: { username: public_user.username } expect(assigns[:events]).not_to be_empty end end @@ -199,7 +199,7 @@ describe UsersController do push_data = Gitlab::DataBuilder::Push.build_sample(project, private_user) EventCreateService.new.push(project, private_user, push_data) - get :calendar_activities, username: private_user.username + get :calendar_activities, params: { username: private_user.username } expect(response).to have_gitlab_http_status(:not_found) end end @@ -213,7 +213,7 @@ describe UsersController do context 'format html' do it 'renders snippets page' do - get :snippets, username: user.username + get :snippets, params: { username: user.username } expect(response).to have_gitlab_http_status(200) expect(response).to render_template('show') end @@ -221,7 +221,7 @@ describe UsersController do context 'format json' do it 'response with snippets json data' do - get :snippets, username: user.username, format: :json + get :snippets, params: { username: user.username }, format: :json expect(response).to have_gitlab_http_status(200) expect(JSON.parse(response.body)).to have_key('html') end @@ -235,7 +235,7 @@ describe UsersController do context 'when user exists' do it 'returns JSON indicating the user exists' do - get :exists, username: user.username + get :exists, params: { username: user.username } expected_json = { exists: true }.to_json expect(response.body).to eq(expected_json) @@ -245,7 +245,7 @@ describe UsersController do let(:user) { create(:user, username: 'CamelCaseUser') } it 'returns JSON indicating the user exists' do - get :exists, username: user.username.downcase + get :exists, params: { username: user.username.downcase } expected_json = { exists: true }.to_json expect(response.body).to eq(expected_json) @@ -255,7 +255,7 @@ describe UsersController do context 'when the user does not exist' do it 'returns JSON indicating the user does not exist' do - get :exists, username: 'foo' + get :exists, params: { username: 'foo' } expected_json = { exists: false }.to_json expect(response.body).to eq(expected_json) @@ -265,7 +265,7 @@ describe UsersController do let(:redirect_route) { user.namespace.redirect_routes.create(path: 'old-username') } it 'returns JSON indicating a user by that username does not exist' do - get :exists, username: 'old-username' + get :exists, params: { username: 'old-username' } expected_json = { exists: false }.to_json expect(response.body).to eq(expected_json) @@ -286,7 +286,7 @@ describe UsersController do context 'with exactly matching casing' do it 'responds with success' do - get :show, username: user.username + get :show, params: { username: user.username } expect(response).to be_success end @@ -294,7 +294,7 @@ describe UsersController do context 'with different casing' do it 'redirects to the correct casing' do - get :show, username: user.username.downcase + get :show, params: { username: user.username.downcase } expect(response).to redirect_to(user) expect(controller).not_to set_flash[:notice] @@ -306,7 +306,7 @@ describe UsersController do let(:redirect_route) { user.namespace.redirect_routes.create(path: 'old-path') } it 'redirects to the canonical path' do - get :show, username: redirect_route.path + get :show, params: { username: redirect_route.path } expect(response).to redirect_to(user) expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) @@ -316,7 +316,7 @@ describe UsersController do let(:redirect_route) { user.namespace.redirect_routes.create(path: 'http') } it 'does not modify the requested host' do - get :show, username: redirect_route.path + get :show, params: { username: redirect_route.path } expect(response).to redirect_to(user) expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) @@ -327,7 +327,7 @@ describe UsersController do let(:redirect_route) { user.namespace.redirect_routes.create(path: 'ser') } it 'redirects to the canonical path' do - get :show, username: redirect_route.path + get :show, params: { username: redirect_route.path } expect(response).to redirect_to(user) expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) @@ -342,7 +342,7 @@ describe UsersController do context 'with exactly matching casing' do it 'responds with success' do - get :projects, username: user.username + get :projects, params: { username: user.username } expect(response).to be_success end @@ -350,7 +350,7 @@ describe UsersController do context 'with different casing' do it 'redirects to the correct casing' do - get :projects, username: user.username.downcase + get :projects, params: { username: user.username.downcase } expect(response).to redirect_to(user_projects_path(user)) expect(controller).not_to set_flash[:notice] @@ -362,7 +362,7 @@ describe UsersController do let(:redirect_route) { user.namespace.redirect_routes.create(path: 'old-path') } it 'redirects to the canonical path' do - get :projects, username: redirect_route.path + get :projects, params: { username: redirect_route.path } expect(response).to redirect_to(user_projects_path(user)) expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) @@ -372,7 +372,7 @@ describe UsersController do let(:redirect_route) { user.namespace.redirect_routes.create(path: 'http') } it 'does not modify the requested host' do - get :projects, username: redirect_route.path + get :projects, params: { username: redirect_route.path } expect(response).to redirect_to(user_projects_path(user)) expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) @@ -384,7 +384,7 @@ describe UsersController do # I.e. /users/ser should not become /ufoos/ser it 'does not modify the /users part of the path' do - get :projects, username: redirect_route.path + get :projects, params: { username: redirect_route.path } expect(response).to redirect_to(user_projects_path(user)) expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) diff --git a/spec/db/importers/common_metrics_importer_spec.rb b/spec/db/importers/common_metrics_importer_spec.rb index 68260820958..6133b17ac61 100644 --- a/spec/db/importers/common_metrics_importer_spec.rb +++ b/spec/db/importers/common_metrics_importer_spec.rb @@ -4,12 +4,18 @@ require 'rails_helper' require Rails.root.join("db", "importers", "common_metrics_importer.rb") describe Importers::PrometheusMetric do + let(:existing_group_titles) do + ::PrometheusMetric::GROUP_DETAILS.each_with_object({}) do |(key, value), memo| + memo[key] = value[:group_title] + end + end + it 'group enum equals ::PrometheusMetric' do expect(described_class.groups).to eq(::PrometheusMetric.groups) end it 'GROUP_TITLES equals ::PrometheusMetric' do - expect(described_class::GROUP_TITLES).to eq(::PrometheusMetric::GROUP_TITLES) + expect(described_class::GROUP_TITLES).to eq(existing_group_titles) end end diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb index e8584846b56..7c505ee0d43 100644 --- a/spec/db/schema_spec.rb +++ b/spec/db/schema_spec.rb @@ -54,7 +54,8 @@ describe 'Database schema' do user_agent_details: %w[subject_id], users: %w[color_scheme_id created_by_id theme_id], users_star_projects: %w[user_id], - web_hooks: %w[service_id] + web_hooks: %w[service_id], + suggestions: %w[commit_id] }.with_indifferent_access.freeze context 'for table' do diff --git a/spec/factories/appearances.rb b/spec/factories/appearances.rb index 18c7453bd1b..dd5129229d4 100644 --- a/spec/factories/appearances.rb +++ b/spec/factories/appearances.rb @@ -15,6 +15,10 @@ FactoryBot.define do header_logo { fixture_file_upload('spec/fixtures/dk.png') } end + trait :with_favicon do + favicon { fixture_file_upload('spec/fixtures/dk.png') } + end + trait :with_logos do with_logo with_header_logo diff --git a/spec/factories/ci/bridge.rb b/spec/factories/ci/bridge.rb new file mode 100644 index 00000000000..5f83b80ad7b --- /dev/null +++ b/spec/factories/ci/bridge.rb @@ -0,0 +1,17 @@ +FactoryBot.define do + factory :ci_bridge, class: Ci::Bridge do + name ' bridge' + stage 'test' + stage_idx 0 + ref 'master' + tag false + created_at 'Di 29. Okt 09:50:00 CET 2013' + status :success + + pipeline factory: :ci_pipeline + + after(:build) do |bridge, evaluator| + bridge.project ||= bridge.pipeline.project + end + end +end diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb index 2d1f48bf249..c51f2f958f9 100644 --- a/spec/factories/notes.rb +++ b/spec/factories/notes.rb @@ -64,6 +64,21 @@ FactoryBot.define do resolved_at { Time.now } resolved_by { create(:user) } end + + factory :image_diff_note_on_merge_request do + position do + Gitlab::Diff::Position.new( + old_path: "files/images/any_image.png", + new_path: "files/images/any_image.png", + width: 10, + height: 10, + x: 1, + y: 1, + diff_refs: diff_refs, + position_type: "image" + ) + end + end end factory :diff_note_on_commit, traits: [:on_commit], class: DiffNote do diff --git a/spec/factories/pool_repositories.rb b/spec/factories/pool_repositories.rb index 265a4643f46..36e54cf44b4 100644 --- a/spec/factories/pool_repositories.rb +++ b/spec/factories/pool_repositories.rb @@ -15,6 +15,10 @@ FactoryBot.define do state :failed end + trait :obsolete do + state :obsolete + end + trait :ready do state :ready diff --git a/spec/factories/project_repositories.rb b/spec/factories/project_repositories.rb new file mode 100644 index 00000000000..39e8ea2e11e --- /dev/null +++ b/spec/factories/project_repositories.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :project_repository do + project + + after(:build) do |project_repository, _| + project_repository.shard_name = project_repository.project.repository_storage + project_repository.disk_path = project_repository.project.disk_path + end + end +end diff --git a/spec/factories/releases.rb b/spec/factories/releases.rb index d80c65cf8bb..cab6b4a811f 100644 --- a/spec/factories/releases.rb +++ b/spec/factories/releases.rb @@ -1,7 +1,15 @@ FactoryBot.define do factory :release do tag "v1.1.0" + sha 'b83d6e391c22777fca1ed3012fce84f633d7fed0' + name { tag } description "Awesome release" project + author + + trait :legacy do + sha nil + author nil + end end end diff --git a/spec/factories/suggestions.rb b/spec/factories/suggestions.rb new file mode 100644 index 00000000000..307523cc061 --- /dev/null +++ b/spec/factories/suggestions.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :suggestion do + relative_order 0 + association :note, factory: :diff_note_on_merge_request + from_content " vars = {\n" + to_content " vars = [\n" + + trait :unappliable do + from_content "foo" + to_content "foo" + end + + trait :applied do + applied true + commit_id { RepoHelpers.sample_commit.id } + end + end +end diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb index 91c22e7ad82..f066b088800 100644 --- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb +++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb @@ -1,7 +1,8 @@ require 'rails_helper' -describe 'Admin disables Git access protocol' do +describe 'Admin disables Git access protocol', :js do include StubENV + include MobileHelpers let(:project) { create(:project, :empty_repo) } let(:admin) { create(:admin) } @@ -20,7 +21,24 @@ describe 'Admin disables Git access protocol' do visit_project expect(page).to have_content("git clone #{project.ssh_url_to_repo}") - expect(page).not_to have_selector('#clone-dropdown') + + find('.clone-dropdown-btn').click + + within('.git-clone-holder') do + expect(page).to have_content('Clone with SSH') + expect(page).not_to have_content('Clone with HTTP') + end + end + + context 'mobile component' do + it 'shows only the SSH clone information' do + resize_screen_xs + visit_project + find('.dropdown-toggle').click + + expect(page).to have_content('Copy SSH clone URL') + expect(page).not_to have_content('Copy HTTP clone URL') + end end end @@ -31,9 +49,25 @@ describe 'Admin disables Git access protocol' do it 'shows only HTTP url' do visit_project + find('.clone-dropdown-btn').click expect(page).to have_content("git clone #{project.http_url_to_repo}") - expect(page).not_to have_selector('#clone-dropdown') + + within('.git-clone-holder') do + expect(page).to have_content('Clone with HTTP') + expect(page).not_to have_content('Clone with SSH') + end + end + + context 'mobile component' do + it 'shows only the HTTP clone information' do + resize_screen_xs + visit_project + find('.dropdown-toggle').click + + expect(page).to have_content('Copy HTTP clone URL') + expect(page).not_to have_content('Copy SSH clone URL') + end end end @@ -46,7 +80,24 @@ describe 'Admin disables Git access protocol' do visit_project expect(page).to have_content("git clone #{project.ssh_url_to_repo}") - expect(page).to have_selector('#clone-dropdown') + + find('.clone-dropdown-btn').click + + within('.git-clone-holder') do + expect(page).to have_content('Clone with SSH') + expect(page).to have_content('Clone with HTTP') + end + end + + context 'mobile component' do + it 'shows both SSH and HTTP clone information' do + resize_screen_xs + visit_project + find('.dropdown-toggle').click + + expect(page).to have_content('Copy HTTP clone URL') + expect(page).to have_content('Copy SSH clone URL') + end end end diff --git a/spec/features/group_variables_spec.rb b/spec/features/group_variables_spec.rb index 89e0cdd8ed7..57e3ddfb39c 100644 --- a/spec/features/group_variables_spec.rb +++ b/spec/features/group_variables_spec.rb @@ -7,7 +7,7 @@ describe 'Group variables', :js do let(:page_path) { group_settings_ci_cd_path(group) } before do - group.add_maintainer(user) + group.add_owner(user) gitlab_sign_in(user) visit page_path diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb index 4e6f73ef58a..9671a4d8c49 100644 --- a/spec/features/groups/show_spec.rb +++ b/spec/features/groups/show_spec.rb @@ -65,7 +65,7 @@ describe 'Group show page' do context 'when subgroups are supported', :js, :nested_groups do before do - allow(Group).to receive(:supports_nested_groups?) { true } + allow(Group).to receive(:supports_nested_objects?) { true } visit path end @@ -76,7 +76,7 @@ describe 'Group show page' do context 'when subgroups are not supported' do before do - allow(Group).to receive(:supports_nested_groups?) { false } + allow(Group).to receive(:supports_nested_objects?) { false } visit path end diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb index c29dfb01381..e24b1f4349d 100644 --- a/spec/features/help_pages_spec.rb +++ b/spec/features/help_pages_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'Help Pages' do @@ -52,23 +54,21 @@ describe 'Help Pages' do end end - context 'in a production environment with version check enabled', :js do + context 'in a production environment with version check enabled' do before do - allow(Rails.env).to receive(:production?) { true } stub_application_setting(version_check_enabled: true) - allow_any_instance_of(VersionCheck).to receive(:url) { '/version-check-url' } + + allow(Rails.env).to receive(:production?).and_return(true) + allow(VersionCheck).to receive(:url).and_return('/version-check-url') sign_in(create(:user)) visit help_path end it 'has a version check image' do - expect(find('.js-version-status-badge', visible: false)['src']).to end_with('/version-check-url') - end - - it 'hides the version check image if the image request fails' do - # We use '--load-images=yes' with poltergeist so the image fails to load - expect(page).to have_selector('.js-version-status-badge', visible: false) + # Check `data-src` due to lazy image loading + expect(find('.js-version-status-badge', visible: false)['data-src']) + .to end_with('/version-check-url') end end diff --git a/spec/features/ics/project_issues_spec.rb b/spec/features/ics/project_issues_spec.rb index 2ca3d52a5be..54143595e6b 100644 --- a/spec/features/ics/project_issues_spec.rb +++ b/spec/features/ics/project_issues_spec.rb @@ -72,5 +72,14 @@ describe 'Project Issues Calendar Feed' do expect(body).to have_text('TRANSP:TRANSPARENT') end end + + context 'sorted by priority' do + it 'renders calendar feed' do + visit project_issues_path(project, :ics, sort: 'priority', feed_token: user.feed_token) + + expect(response_headers['Content-Type']).to have_content('text/calendar') + expect(body).to have_text('BEGIN:VCALENDAR') + end + end end end diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index d7531d5fcd9..3b7a17ef355 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -3,6 +3,8 @@ require 'rails_helper' describe 'GFM autocomplete', :js do let(:issue_xss_title) { 'This will execute alert<img src=x onerror=alert(2)<img src=x onerror=alert(1)>' } let(:user_xss_title) { 'eve <img src=x onerror=alert(2)<img src=x onerror=alert(1)>' } + let(:label_xss_title) { 'alert label <img src=x onerror="alert(\'Hello xss\');" a'} + let(:milestone_xss_title) { 'alert milestone <img src=x onerror="alert(\'Hello xss\');" a' } let(:user_xss) { create(:user, name: user_xss_title, username: 'xss.user') } let(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') } @@ -25,10 +27,14 @@ describe 'GFM autocomplete', :js do simulate_input('#issue-description', "@#{user.name[0...3]}") + wait_for_requests + find('.atwho-view .cur').click click_button 'Save changes' + wait_for_requests + expect(find('.description')).to have_content(user.to_reference) end @@ -47,6 +53,8 @@ describe 'GFM autocomplete', :js do find('#note-body').native.send_keys('#') end + wait_for_requests + expect(page).to have_selector('.atwho-container') page.within '.atwho-container #at-view-issues' do @@ -59,6 +67,8 @@ describe 'GFM autocomplete', :js do find('#note-body').native.send_keys('@ev') end + wait_for_requests + expect(page).to have_selector('.atwho-container') page.within '.atwho-container #at-view-users' do @@ -66,6 +76,22 @@ describe 'GFM autocomplete', :js do end end + it 'opens autocomplete menu for Milestone when field starts with text with item escaping HTML characters' do + create(:milestone, project: project, title: milestone_xss_title) + + page.within '.timeline-content-form' do + find('#note-body').native.send_keys('%') + end + + wait_for_requests + + expect(page).to have_selector('.atwho-container') + + page.within '.atwho-container #at-view-milestones' do + expect(find('li').text).to have_content('alert milestone') + end + end + it 'doesnt open autocomplete menu character is prefixed with text' do page.within '.timeline-content-form' do find('#note-body').native.send_keys('testing') @@ -258,12 +284,28 @@ describe 'GFM autocomplete', :js do let!(:bug) { create(:label, project: project, title: 'bug') } let!(:feature_proposal) { create(:label, project: project, title: 'feature proposal') } + it 'opens autocomplete menu for Labels when field starts with text with item escaping HTML characters' do + create(:label, project: project, title: label_xss_title) + + note = find('#note-body') + + # It should show all the labels on "~". + type(note, '~') + + wait_for_requests + + page.within '.atwho-container #at-view-labels' do + expect(find('.atwho-view-ul').text).to have_content('alert label') + end + end + context 'when no labels are assigned' do it 'shows labels' do note = find('#note-body') # It should show all the labels on "~". type(note, '~') + wait_for_requests expect_labels(shown: [backend, bug, feature_proposal]) # It should show all the labels on "/label ~". @@ -290,6 +332,7 @@ describe 'GFM autocomplete', :js do # It should show all the labels on "~". type(note, '~') + wait_for_requests expect_labels(shown: [backend, bug, feature_proposal]) # It should show only unset labels on "/label ~". @@ -316,6 +359,7 @@ describe 'GFM autocomplete', :js do # It should show all the labels on "~". type(note, '~') + wait_for_requests expect_labels(shown: [backend, bug, feature_proposal]) # It should show no labels on "/label ~". diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb index 687a6f1eafc..e60486f6dcb 100644 --- a/spec/features/issues/user_creates_issue_spec.rb +++ b/spec/features/issues/user_creates_issue_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" describe "User creates issue" do @@ -12,7 +14,7 @@ describe "User creates issue" do visit(new_project_issue_path(project)) end - it "creates issue" do + it "creates issue", :js do page.within(".issue-form") do expect(page).to have_no_content("Assign to") .and have_no_content("Labels") @@ -25,11 +27,15 @@ describe "User creates issue" do issue_title = "500 error on profile" fill_in("Title", with: issue_title) + first('.js-md').click + first('.qa-issuable-form-description').native.send_keys('Description') + click_button("Submit issue") expect(page).to have_content(issue_title) .and have_content(user.name) .and have_content(project.name) + expect(page).to have_selector('strong', text: 'Description') end end @@ -64,10 +70,10 @@ describe "User creates issue" do end context "with labels" do - LABEL_TITLES = %w(bug feature enhancement).freeze + let(:label_titles) { %w(bug feature enhancement) } before do - LABEL_TITLES.each do |title| + label_titles.each do |title| create(:label, project: project, title: title) end end @@ -77,13 +83,13 @@ describe "User creates issue" do fill_in("Title", with: issue_title) click_button("Label") - click_link(LABEL_TITLES.first) + click_link(label_titles.first) click_button("Submit issue") expect(page).to have_content(issue_title) .and have_content(user.name) .and have_content(project.name) - .and have_content(LABEL_TITLES.first) + .and have_content(label_titles.first) end end end diff --git a/spec/features/merge_request/user_awards_emoji_spec.rb b/spec/features/merge_request/user_awards_emoji_spec.rb index 859a4c65562..93376bc8ce0 100644 --- a/spec/features/merge_request/user_awards_emoji_spec.rb +++ b/spec/features/merge_request/user_awards_emoji_spec.rb @@ -4,11 +4,14 @@ describe 'Merge request > User awards emoji', :js do let(:project) { create(:project, :public, :repository) } let(:user) { project.creator } let(:merge_request) { create(:merge_request, source_project: project, author: create(:user)) } + let!(:note) { create(:note, noteable: merge_request, project: merge_request.project) } describe 'logged in' do before do sign_in(user) visit project_merge_request_path(project, merge_request) + + wait_for_requests end it 'adds award to merge request' do @@ -36,6 +39,15 @@ describe 'Merge request > User awards emoji', :js do expect(page).to have_selector('.emoji-menu', count: 1) end + it 'adds awards to note' do + first('.js-note-emoji').click + first('.emoji-menu .js-emoji-btn').click + + wait_for_requests + + expect(page).to have_selector('.js-awards-block') + end + describe 'the project is archived' do let(:project) { create(:project, :public, :repository, :archived) } diff --git a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb index d790bdc82ce..d19408ee87f 100644 --- a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb +++ b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb @@ -90,9 +90,6 @@ describe 'Merge request > User creates image diff notes', :js do %w(inline parallel).each do |view| context "#{view} view" do - let(:merge_request) { create(:merge_request_with_diffs, :with_image_diffs, source_project: project, author: user) } - let(:path) { "files/images/ee_repo_logo.png" } - let(:position) do Gitlab::Diff::Position.new( old_path: path, @@ -108,9 +105,11 @@ describe 'Merge request > User creates image diff notes', :js do let!(:note) { create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) } - describe 'creating a new diff note' do + shared_examples 'creates image diff note' do before do visit diffs_project_merge_request_path(project, merge_request, view: view) + wait_for_requests + create_image_diff_note end @@ -132,6 +131,32 @@ describe 'Merge request > User creates image diff notes', :js do expect(page).to have_content('image diff test comment') end end + + context 'when images are not stored in LFS' do + let(:merge_request) { create(:merge_request_with_diffs, :with_image_diffs, source_project: project, author: user) } + let(:path) { 'files/images/ee_repo_logo.png' } + + it_behaves_like 'creates image diff note' + end + + context 'when images are stored in LFS' do + let(:merge_request) { create(:merge_request, source_project: project, target_project: project, source_branch: 'png-lfs', target_branch: 'master', author: user) } + let(:path) { 'files/images/logo-black.png' } + + before do + allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) + project.update_attribute(:lfs_enabled, true) + end + + it 'shows lfs badges' do + visit diffs_project_merge_request_path(project, merge_request, view: view) + wait_for_requests + + expect(page.all('.diff-file span.label-lfs', visible: :all)).not_to be_empty + end + + it_behaves_like 'creates image diff note' + end end end diff --git a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb index 53ed5d78598..29b3d2b629b 100644 --- a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb @@ -88,6 +88,8 @@ describe 'Merge request > User merges when pipeline succeeds', :js do describe 'enabling Merge when pipeline succeeds via dropdown' do it 'activates the Merge when pipeline succeeds feature' do + wait_for_requests + find('.js-merge-moment').click click_link 'Merge when pipeline succeeds' diff --git a/spec/features/merge_request/user_sees_diff_spec.rb b/spec/features/merge_request/user_sees_diff_spec.rb index 0df9e4bbc1a..04b07525919 100644 --- a/spec/features/merge_request/user_sees_diff_spec.rb +++ b/spec/features/merge_request/user_sees_diff_spec.rb @@ -87,20 +87,6 @@ describe 'Merge request > User sees diff', :js do let(:current_user) { project.owner } let(:branch_name) {"test_branch"} - def create_file(branch_name, file_name, content) - Files::CreateService.new( - project, - current_user, - start_branch: branch_name, - branch_name: branch_name, - commit_message: "Create file", - file_path: file_name, - file_content: content - ).execute - - project.commit(branch_name) - end - it 'escapes any HTML special characters in the diff chunk header' do file_content = <<~CONTENT @@ -136,5 +122,61 @@ describe 'Merge request > User sees diff', :js do expect(page).to have_css(".line[lang='rust'] .k") end end + + context 'when file is stored in LFS' do + let(:merge_request) { create(:merge_request, source_project: project) } + let(:current_user) { project.owner } + + context 'when LFS is enabled on the project' do + before do + allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) + project.update_attribute(:lfs_enabled, true) + + create_file('master', file_name, project.repository.blob_at('master', 'files/lfs/lfs_object.iso').data) + + visit diffs_project_merge_request_path(project, merge_request) + end + + context 'when file is an image', :js do + let(:file_name) { 'files/lfs/image.png' } + + it 'shows an error message' do + expect(page).not_to have_content('could not be displayed because it is stored in LFS') + end + end + + context 'when file is not an image' do + let(:file_name) { 'files/lfs/ruby.rb' } + + it 'shows an error message' do + expect(page).to have_content('This source diff could not be displayed because it is stored in LFS') + end + end + end + + context 'when LFS is not enabled' do + before do + visit diffs_project_merge_request_path(project, merge_request) + end + + it 'displays the diff' do + expect(page).to have_content('size 1575078') + end + end + end + + def create_file(branch_name, file_name, content) + Files::CreateService.new( + project, + current_user, + start_branch: branch_name, + branch_name: branch_name, + commit_message: "Create file", + file_path: file_name, + file_content: content + ).execute + + project.commit(branch_name) + end end end diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb index f7512294bef..63d8decc2d2 100644 --- a/spec/features/merge_request/user_sees_versions_spec.rb +++ b/spec/features/merge_request/user_sees_versions_spec.rb @@ -64,6 +64,17 @@ describe 'Merge request > User sees versions', :js do end end + it 'shows the commit SHAs for every version in the dropdown' do + page.within '.mr-version-dropdown' do + find('.btn-default').click + + page.within('.dropdown-content') do + shas = merge_request.merge_request_diffs.map { |diff| Commit.truncate_sha(diff.head_commit_sha) } + shas.each { |sha| expect(page).to have_content(sha) } + end + end + end + it 'shows comments that were last relevant at that version' do expect(page).to have_content '5 changed files' diff --git a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb new file mode 100644 index 00000000000..c19e299097e --- /dev/null +++ b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'User comments on a diff', :js do + include MergeRequestDiffHelpers + include RepoHelpers + + let(:project) { create(:project, :repository) } + let(:merge_request) do + create(:merge_request_with_diffs, source_project: project, target_project: project, source_branch: 'merge-test') + end + let(:user) { create(:user) } + + before do + project.add_maintainer(user) + sign_in(user) + + visit(diffs_project_merge_request_path(project, merge_request)) + end + + context 'single suggestion note' do + it 'suggestion is presented' do + click_diff_line(find("[id='#{sample_compare.changes[1][:line_code]}']")) + + page.within('.js-discussion-note-form') do + fill_in('note_note', with: "```suggestion\n# change to a comment\n```") + click_button('Comment') + end + + wait_for_requests + + page.within('.diff-discussions') do + expect(page).to have_button('Apply suggestion') + expect(page).to have_content('Suggested change') + expect(page).to have_content(' url = https://github.com/gitlabhq/gitlab-shell.git') + expect(page).to have_content('# change to a comment') + end + end + + it 'suggestion is appliable' do + click_diff_line(find("[id='#{sample_compare.changes[1][:line_code]}']")) + + page.within('.js-discussion-note-form') do + fill_in('note_note', with: "```suggestion\n# change to a comment\n```") + click_button('Comment') + end + + wait_for_requests + + page.within('.diff-discussions') do + expect(page).not_to have_content('Applied') + + click_button('Apply suggestion') + wait_for_requests + + expect(page).to have_content('Applied') + end + end + end + + context 'multiple suggestions in a single note' do + it 'suggestions are presented' do + click_diff_line(find("[id='#{sample_compare.changes[1][:line_code]}']")) + + page.within('.js-discussion-note-form') do + fill_in('note_note', with: "```suggestion\n# change to a comment\n```\n```suggestion\n# or that\n```") + click_button('Comment') + end + + wait_for_requests + + page.within('.diff-discussions') do + suggestion_1 = page.all(:css, '.md-suggestion-diff')[0] + suggestion_2 = page.all(:css, '.md-suggestion-diff')[1] + + expect(suggestion_1).to have_content(' url = https://github.com/gitlabhq/gitlab-shell.git') + expect(suggestion_1).to have_content('# change to a comment') + + expect(suggestion_2).to have_content(' url = https://github.com/gitlabhq/gitlab-shell.git') + expect(suggestion_2).to have_content('# or that') + end + end + end +end diff --git a/spec/features/merge_request/user_tries_to_access_private_repository_through_new_mr_spec.rb b/spec/features/merge_request/user_tries_to_access_private_repository_through_new_mr_spec.rb new file mode 100644 index 00000000000..9318b5f1ebb --- /dev/null +++ b/spec/features/merge_request/user_tries_to_access_private_repository_through_new_mr_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe 'Merge Request > Tries to access private repo of public project' do + let(:current_user) { create(:user) } + let(:private_project) do + create(:project, :public, :repository, + path: 'nothing-to-see-here', + name: 'nothing to see here', + repository_access_level: ProjectFeature::PRIVATE) + end + let(:owned_project) do + create(:project, :public, :repository, + namespace: current_user.namespace, + creator: current_user) + end + + context 'when the user enters the querystring info for the other project' do + let(:mr_path) do + project_new_merge_request_diffs_path( + owned_project, + merge_request: { + source_project_id: private_project.id, + source_branch: 'feature' + } + ) + end + + before do + sign_in current_user + visit mr_path + end + + it "does not mention the project the user can't see the repo of" do + expect(page).not_to have_content('nothing-to-see-here') + end + end +end diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb index 5e0434c1c2c..f45bcabd196 100644 --- a/spec/features/profiles/user_edit_profile_spec.rb +++ b/spec/features/profiles/user_edit_profile_spec.rb @@ -147,6 +147,9 @@ describe 'User edit profile' do end context 'user menu' do + let(:issue) { create(:issue, project: project)} + let(:project) { create(:project) } + def open_user_status_modal find('.header-user-dropdown-toggle').click @@ -205,6 +208,17 @@ describe 'User edit profile' do end end + it 'does not update the awards panel emoji' do + project.add_maintainer(user) + visit(project_issue_path(project, issue)) + + emoji = 'biohazard' + open_user_status_modal + select_emoji(emoji, true) + + expect(page.all('.award-control .js-counter')).to all(have_content('0')) + end + it 'adds message to user status' do message = 'I have something to say' open_user_status_modal diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index 3d17eb3a73a..06e30571336 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -130,7 +130,7 @@ describe 'Gcp Cluster', :js do context 'when user changes cluster parameters' do before do - allow(ClusterPlatformConfigureWorker).to receive(:perform_async) + allow(ClusterConfigureWorker).to receive(:perform_async) fill_in 'cluster_platform_kubernetes_attributes_namespace', with: 'my-namespace' page.within('#js-cluster-details') { click_button 'Save changes' } end diff --git a/spec/features/projects/commits/user_browses_commits_spec.rb b/spec/features/projects/commits/user_browses_commits_spec.rb index 2159adf49fc..574a8aefd63 100644 --- a/spec/features/projects/commits/user_browses_commits_spec.rb +++ b/spec/features/projects/commits/user_browses_commits_spec.rb @@ -93,7 +93,7 @@ describe 'User browses commits' do it 'shows a blank label' do allow_any_instance_of(Gitlab::Diff::File).to receive(:blob).and_return(nil) - allow_any_instance_of(Gitlab::Diff::File).to receive(:raw_binary?).and_return(true) + allow_any_instance_of(Gitlab::Diff::File).to receive(:binary?).and_return(true) visit(project_commit_path(project, commit)) diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 651c02c7ecc..60f37f4b74a 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -351,8 +351,8 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do context 'when user is a maintainer' do shared_examples 'no reveal button variables behavior' do it 'renders a hidden value with no reveal values button', :js do - expect(page).to have_content('Token') - expect(page).to have_content('Variables') + expect(page).to have_content('Trigger token') + expect(page).to have_content('Trigger variables') expect(page).not_to have_css('.js-reveal-variables') @@ -389,8 +389,8 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do shared_examples 'reveal button variables behavior' do it 'renders a hidden value with a reveal values button', :js do - expect(page).to have_content('Token') - expect(page).to have_content('Variables') + expect(page).to have_content('Trigger token') + expect(page).to have_content('Trigger variables') expect(page).to have_css('.js-reveal-variables') diff --git a/spec/features/projects/labels/user_views_labels_spec.rb b/spec/features/projects/labels/user_views_labels_spec.rb index 0cbeca4e392..2c8267764bd 100644 --- a/spec/features/projects/labels/user_views_labels_spec.rb +++ b/spec/features/projects/labels/user_views_labels_spec.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + require "spec_helper" describe "User views labels" do set(:project) { create(:project_empty_repo, :public) } set(:user) { create(:user) } - LABEL_TITLES = %w[bug enhancement feature].freeze + let(:label_titles) { %w[bug enhancement feature] } before do - LABEL_TITLES.each { |title| create(:label, project: project, title: title) } + label_titles.each { |title| create(:label, project: project, title: title) } project.add_guest(user) sign_in(user) @@ -17,7 +19,7 @@ describe "User views labels" do it "shows all labels" do page.within('.other-labels .manage-labels-list') do - LABEL_TITLES.each { |title| expect(page).to have_content(title) } + label_titles.each { |title| expect(page).to have_content(title) } end end end diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index 418e22f8c35..1982136b89d 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -200,35 +200,21 @@ describe 'Projects > Settings > Repository settings' do context 'repository cleanup settings' do let(:object_map_file) { Rails.root.join('spec', 'fixtures', 'bfg_object_map.txt') } - context 'feature enabled' do - it 'uploads an object map file', :js do - stub_feature_flags(project_cleanup: true) - - visit project_settings_repository_path(project) + it 'uploads an object map file', :js do + visit project_settings_repository_path(project) - expect(page).to have_content('Repository cleanup') + expect(page).to have_content('Repository cleanup') - page.within('#cleanup') do - attach_file('project[bfg_object_map]', object_map_file, visible: false) + page.within('#cleanup') do + attach_file('project[bfg_object_map]', object_map_file, visible: false) - Sidekiq::Testing.fake! do - click_button 'Start cleanup' - end + Sidekiq::Testing.fake! do + click_button 'Start cleanup' end - - expect(page).to have_content('Repository cleanup has started') - expect(RepositoryCleanupWorker.jobs.count).to eq(1) end - end - context 'feature disabled' do - it 'does not show the settings' do - stub_feature_flags(project_cleanup: false) - - visit project_settings_repository_path(project) - - expect(page).not_to have_content('Repository cleanup') - end + expect(page).to have_content('Repository cleanup has started') + expect(RepositoryCleanupWorker.jobs.count).to eq(1) end end end diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index cb7a912946c..09de983f669 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -259,8 +259,9 @@ describe 'Runners' do context 'group runners in group settings' do let(:group) { create(:group) } + before do - group.add_maintainer(user) + group.add_owner(user) end context 'group with no runners' do diff --git a/spec/features/users/overview_spec.rb b/spec/features/users/overview_spec.rb index 34ed771340f..873de85708a 100644 --- a/spec/features/users/overview_spec.rb +++ b/spec/features/users/overview_spec.rb @@ -119,6 +119,12 @@ describe 'Overview tab on a user profile', :js do it 'shows a link to the project list' do expect(find('#js-overview .projects-block')).to have_selector('.js-view-all', visible: true) end + + it 'shows projects in "compact mode"' do + page.within('#js-overview .projects-block') do + expect(find('.js-projects-list-holder')).to have_selector('.compact') + end + end end describe 'user has more than ten personal projects' do diff --git a/spec/finders/cluster_ancestors_finder_spec.rb b/spec/finders/cluster_ancestors_finder_spec.rb new file mode 100644 index 00000000000..332086c42e2 --- /dev/null +++ b/spec/finders/cluster_ancestors_finder_spec.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ClusterAncestorsFinder, '#execute' do + let(:group) { create(:group) } + let(:project) { create(:project, group: group) } + let(:user) { create(:user) } + + let!(:project_cluster) do + create(:cluster, :provided_by_user, cluster_type: :project_type, projects: [project]) + end + + let!(:group_cluster) do + create(:cluster, :provided_by_user, cluster_type: :group_type, groups: [group]) + end + + subject { described_class.new(clusterable, user).execute } + + context 'for a project' do + let(:clusterable) { project } + + before do + project.add_maintainer(user) + end + + it 'returns the project clusters followed by group clusters' do + is_expected.to eq([project_cluster, group_cluster]) + end + + context 'nested groups', :nested_groups do + let(:group) { create(:group, parent: parent_group) } + let(:parent_group) { create(:group) } + + let!(:parent_group_cluster) do + create(:cluster, :provided_by_user, cluster_type: :group_type, groups: [parent_group]) + end + + it 'returns the project clusters followed by group clusters ordered ascending the hierarchy' do + is_expected.to eq([project_cluster, group_cluster, parent_group_cluster]) + end + end + end + + context 'user cannot read clusters for clusterable' do + let(:clusterable) { project } + + it 'returns nothing' do + is_expected.to be_empty + end + end + + context 'for a group' do + let(:clusterable) { group } + + before do + group.add_maintainer(user) + end + + it 'returns the list of group clusters' do + is_expected.to eq([group_cluster]) + end + + context 'nested groups', :nested_groups do + let(:group) { create(:group, parent: parent_group) } + let(:parent_group) { create(:group) } + + let!(:parent_group_cluster) do + create(:cluster, :provided_by_user, cluster_type: :group_type, groups: [parent_group]) + end + + it 'returns the list of group clusters ordered ascending the hierarchy' do + is_expected.to eq([group_cluster, parent_group_cluster]) + end + end + end +end diff --git a/spec/finders/concerns/finder_with_cross_project_access_spec.rb b/spec/finders/concerns/finder_with_cross_project_access_spec.rb index 1ff65a8101b..f29acb521a8 100644 --- a/spec/finders/concerns/finder_with_cross_project_access_spec.rb +++ b/spec/finders/concerns/finder_with_cross_project_access_spec.rb @@ -115,4 +115,20 @@ describe FinderWithCrossProjectAccess do expect(finder.execute).to include(result) end end + + context 'when specifying a model' do + let(:finder_class) do + Class.new do + prepend FinderWithCrossProjectAccess + + requires_cross_project_access model: Project + end + end + + context '.finder_model' do + it 'is set correctly' do + expect(finder_class.finder_model).to eq(Project) + end + end + end end diff --git a/spec/finders/events_finder_spec.rb b/spec/finders/events_finder_spec.rb index 62968e83292..3bce46cc4d1 100644 --- a/spec/finders/events_finder_spec.rb +++ b/spec/finders/events_finder_spec.rb @@ -14,6 +14,10 @@ describe EventsFinder do let!(:closed_issue_event2) { create(:event, project: project1, author: user, target: closed_issue, action: Event::CLOSED, created_at: Date.new(2016, 2, 2)) } let!(:opened_merge_request_event2) { create(:event, project: project2, author: user, target: opened_merge_request, action: Event::CREATED, created_at: Date.new(2017, 2, 2)) } + let(:public_project) { create(:project, :public, creator_id: user.id, namespace: user.namespace) } + let(:confidential_issue) { create(:closed_issue, confidential: true, project: public_project, author: user) } + let!(:confidential_event) { create(:event, project: public_project, author: user, target: confidential_issue, action: Event::CLOSED) } + context 'when targeting a user' do it 'returns events between specified dates filtered on action and type' do events = described_class.new(source: user, current_user: user, action: 'created', target_type: 'merge_request', after: Date.new(2017, 1, 1), before: Date.new(2017, 2, 1)).execute @@ -27,6 +31,19 @@ describe EventsFinder do expect(events).not_to include(opened_merge_request_event) end + it 'does not include events on confidential issues the user does not have access to' do + events = described_class.new(source: user, current_user: other_user).execute + + expect(events).not_to include(confidential_event) + end + + it 'includes confidential events user has access to' do + public_project.add_developer(other_user) + events = described_class.new(source: user, current_user: other_user).execute + + expect(events).to include(confidential_event) + end + it 'returns nothing when the current user cannot read cross project' do expect(Ability).to receive(:allowed?).with(user, :read_cross_project) { false } diff --git a/spec/finders/releases_finder_spec.rb b/spec/finders/releases_finder_spec.rb new file mode 100644 index 00000000000..32ee15134a2 --- /dev/null +++ b/spec/finders/releases_finder_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ReleasesFinder do + let(:user) { create(:user) } + let(:project) { create(:project, :repository) } + let(:repository) { project.repository } + let(:v1_0_0) { create(:release, project: project, tag: 'v1.0.0') } + let(:v1_1_0) { create(:release, project: project, tag: 'v1.1.0') } + + subject { described_class.new(project, user)} + + before do + v1_0_0.update_attribute(:created_at, 2.days.ago) + v1_1_0.update_attribute(:created_at, 1.day.ago) + end + + describe '#execute' do + context 'when the user is not part of the project' do + it 'returns no releases' do + releases = subject.execute + + expect(releases).to be_empty + end + end + + context 'when the user is a project developer' do + before do + project.add_developer(user) + end + + it 'sorts by creation date' do + releases = subject.execute + + expect(releases).to be_present + expect(releases.size).to eq(2) + expect(releases).to eq([v1_1_0, v1_0_0]) + end + end + end +end diff --git a/spec/finders/user_recent_events_finder_spec.rb b/spec/finders/user_recent_events_finder_spec.rb index c5fcd68eb4c..5ebceeb7586 100644 --- a/spec/finders/user_recent_events_finder_spec.rb +++ b/spec/finders/user_recent_events_finder_spec.rb @@ -29,8 +29,9 @@ describe UserRecentEventsFinder do end it 'does not include the events if the user cannot read cross project' do - expect(Ability).to receive(:allowed?).and_call_original + allow(Ability).to receive(:allowed?).and_call_original expect(Ability).to receive(:allowed?).with(current_user, :read_cross_project) { false } + expect(finder.execute).to be_empty end end diff --git a/spec/fixtures/api/schemas/entities/diff_line.json b/spec/fixtures/api/schemas/entities/diff_line.json index 66e8b443e1b..9657004cd2d 100644 --- a/spec/fixtures/api/schemas/entities/diff_line.json +++ b/spec/fixtures/api/schemas/entities/diff_line.json @@ -8,7 +8,8 @@ "new_line": { "type": ["integer", "null"] }, "text": { "type": ["string"] }, "rich_text": { "type": ["string"] }, - "meta_data": { "type": ["object", "null"] } + "meta_data": { "type": ["object", "null"] }, + "can_receive_suggestion": { "type": "boolean" } }, "additionalProperties": false } diff --git a/spec/fixtures/api/schemas/entities/diff_viewer.json b/spec/fixtures/api/schemas/entities/diff_viewer.json index 19780f49a88..81325cd86c6 100644 --- a/spec/fixtures/api/schemas/entities/diff_viewer.json +++ b/spec/fixtures/api/schemas/entities/diff_viewer.json @@ -1,8 +1,20 @@ { "type": "object", - "required": ["name"], + "required": [ + "name" + ], "properties": { - "name": { "type": ["string"] } + "name": { + "type": [ + "string" + ] + }, + "error": { + "type": [ + "string", + "null" + ] + } }, "additionalProperties": false } diff --git a/spec/fixtures/api/schemas/entities/issuable_sidebar_todo.json b/spec/fixtures/api/schemas/entities/issuable_sidebar_todo.json new file mode 100644 index 00000000000..b77e60ece12 --- /dev/null +++ b/spec/fixtures/api/schemas/entities/issuable_sidebar_todo.json @@ -0,0 +1,8 @@ +{ + "type": ["object", "null"], + "properties" : { + "id": { "type": "integer" }, + "delete_path": { "type": "string" } + }, + "additionalProperties": false +} diff --git a/spec/fixtures/api/schemas/entities/issue_sidebar.json b/spec/fixtures/api/schemas/entities/issue_sidebar.json index 682e345d5f5..93adb493d1b 100644 --- a/spec/fixtures/api/schemas/entities/issue_sidebar.json +++ b/spec/fixtures/api/schemas/entities/issue_sidebar.json @@ -2,20 +2,46 @@ "type": "object", "properties" : { "id": { "type": "integer" }, - "iid": { "type": "integer" }, - "subscribed": { "type": "boolean" }, - "time_estimate": { "type": "integer" }, - "total_time_spent": { "type": "integer" }, - "human_time_estimate": { "type": ["integer", "null"] }, - "human_total_time_spent": { "type": ["integer", "null"] }, - "participants": { - "type": "array", - "items": { "$ref": "../public_api/v4/user/basic.json" } + "type": { "type": "string" }, + "author_id": { "type": "integer" }, + "project_id": { "type": "integer" }, + "discussion_locked": { "type": ["boolean", "null"] }, + "due_date": { "type": "date" }, + "confidential": { "type": "boolean" }, + "reference": { "type": "string" }, + "current_user": { + "allOf": [ + { "$ref": "../public_api/v4/user/basic.json" }, + { "type": "object", + "properties" : { + "todo": { "$ref": "issuable_sidebar_todo.json" }, + "can_edit": { "type": "boolean" }, + "can_move": { "type": "boolean" }, + "can_admin_label": { "type": "boolean" } + } + } + ] + }, + "milestone": { + "oneOf": [ + { "type": "null" }, + { "$ref": "../public_api/v4/milestone.json" } + ] }, - "assignees": { + "labels": { "type": "array", - "items": { "$ref": "../public_api/v4/user/basic.json" } - } - }, - "additionalProperties": false + "items": { "$ref": "label.json" } + }, + "issuable_json_path": { "type": "string" }, + "namespace_path": { "type": "string" }, + "project_path": { "type": "string" }, + "project_full_path": { "type": "string" }, + "project_issuables_path": { "type": "string" }, + "create_todo_path": { "type": "string" }, + "project_milestones_path": { "type": "string" }, + "project_labels_path": { "type": "string" }, + "toggle_subscription_path": { "type": "string" }, + "move_issue_path": { "type": "string" }, + "projects_autocomplete_path": { "type": "string" } + } } diff --git a/spec/fixtures/api/schemas/entities/issue_sidebar_extras.json b/spec/fixtures/api/schemas/entities/issue_sidebar_extras.json new file mode 100644 index 00000000000..11be903b083 --- /dev/null +++ b/spec/fixtures/api/schemas/entities/issue_sidebar_extras.json @@ -0,0 +1,18 @@ +{ + "type": "object", + "properties" : { + "subscribed": { "type": "boolean" }, + "time_estimate": { "type": "integer" }, + "total_time_spent": { "type": "integer" }, + "human_time_estimate": { "type": ["integer", "null"] }, + "human_total_time_spent": { "type": ["integer", "null"] }, + "participants": { + "type": "array", + "items": { "$ref": "../public_api/v4/user/basic.json" } + }, + "assignees": { + "type": "array", + "items": { "$ref": "../public_api/v4/user/basic.json" } + } + } +} diff --git a/spec/fixtures/api/schemas/entities/merge_request_basic.json b/spec/fixtures/api/schemas/entities/merge_request_basic.json index cf257ac00de..4c04c838cb8 100644 --- a/spec/fixtures/api/schemas/entities/merge_request_basic.json +++ b/spec/fixtures/api/schemas/entities/merge_request_basic.json @@ -4,15 +4,9 @@ "state": { "type": "string" }, "merge_status": { "type": "string" }, "source_branch_exists": { "type": "boolean" }, - "time_estimate": { "type": "integer" }, - "total_time_spent": { "type": "integer" }, - "human_time_estimate": { "type": ["string", "null"] }, - "human_total_time_spent": { "type": ["string", "null"] }, "merge_error": { "type": ["string", "null"] }, "rebase_in_progress": { "type": "boolean" }, "assignee_id": { "type": ["integer", "null"] }, - "subscribed": { "type": ["boolean", "null"] }, - "participants": { "type": "array" }, "allow_collaboration": { "type": "boolean"}, "allow_maintainer_to_push": { "type": "boolean"}, "assignee": { diff --git a/spec/fixtures/api/schemas/entities/merge_request_sidebar.json b/spec/fixtures/api/schemas/entities/merge_request_sidebar.json new file mode 100644 index 00000000000..7e9e048a9fd --- /dev/null +++ b/spec/fixtures/api/schemas/entities/merge_request_sidebar.json @@ -0,0 +1,56 @@ +{ + "type": "object", + "properties" : { + "id": { "type": "integer" }, + "type": { "type": "string" }, + "author_id": { "type": "integer" }, + "project_id": { "type": "integer" }, + "discussion_locked": { "type": ["boolean", "null"] }, + "reference": { "type": "string" }, + "current_user": { + "allOf": [ + { "$ref": "../public_api/v4/user/basic.json" }, + { "type": "object", + "properties" : { + "todo": { "$ref": "issuable_sidebar_todo.json" }, + "can_edit": { "type": "boolean" }, + "can_move": { "type": "boolean" }, + "can_admin_label": { "type": "boolean" } + } + } + ] + }, + "milestone": { + "oneOf": [ + { "type": "null" }, + { "$ref": "../public_api/v4/milestones.json" } + ] + }, + "labels": { + "type": "array", + "items": { "$ref": "label.json" } + }, + "assignee": { + "allOf": [ + { "$ref": "../public_api/v4/user/basic.json" }, + { "type": "object", + "properties" : { + "can_merge": { "type": "boolean" } + } + } + ] + }, + "issuable_json_path": { "type": "string" }, + "namespace_path": { "type": "string" }, + "project_path": { "type": "string" }, + "project_full_path": { "type": "string" }, + "project_issuables_path": { "type": "string" }, + "create_todo_path": { "type": "string" }, + "project_milestones_path": { "type": "string" }, + "project_labels_path": { "type": "string" }, + "toggle_subscription_path": { "type": "string" }, + "move_issue_path": { "type": "string" }, + "projects_autocomplete_path": { "type": "string" } + }, + "additionalProperties": false +} diff --git a/spec/fixtures/api/schemas/entities/merge_request_sidebar_extras.json b/spec/fixtures/api/schemas/entities/merge_request_sidebar_extras.json new file mode 100644 index 00000000000..682e345d5f5 --- /dev/null +++ b/spec/fixtures/api/schemas/entities/merge_request_sidebar_extras.json @@ -0,0 +1,21 @@ +{ + "type": "object", + "properties" : { + "id": { "type": "integer" }, + "iid": { "type": "integer" }, + "subscribed": { "type": "boolean" }, + "time_estimate": { "type": "integer" }, + "total_time_spent": { "type": "integer" }, + "human_time_estimate": { "type": ["integer", "null"] }, + "human_total_time_spent": { "type": ["integer", "null"] }, + "participants": { + "type": "array", + "items": { "$ref": "../public_api/v4/user/basic.json" } + }, + "assignees": { + "type": "array", + "items": { "$ref": "../public_api/v4/user/basic.json" } + } + }, + "additionalProperties": false +} diff --git a/spec/fixtures/api/schemas/entities/merge_request_widget.json b/spec/fixtures/api/schemas/entities/merge_request_widget.json index 35971d564d5..193ab6821a5 100644 --- a/spec/fixtures/api/schemas/entities/merge_request_widget.json +++ b/spec/fixtures/api/schemas/entities/merge_request_widget.json @@ -119,7 +119,8 @@ "can_push_to_source_branch": { "type": "boolean" }, "rebase_path": { "type": ["string", "null"] }, "squash": { "type": "boolean" }, - "test_reports_path": { "type": ["string", "null"] } + "test_reports_path": { "type": ["string", "null"] }, + "can_receive_suggestion": { "type": "boolean" } }, "additionalProperties": false } diff --git a/spec/fixtures/api/schemas/public_api/v4/milestone.json b/spec/fixtures/api/schemas/public_api/v4/milestone.json new file mode 100644 index 00000000000..6ca2e88ae91 --- /dev/null +++ b/spec/fixtures/api/schemas/public_api/v4/milestone.json @@ -0,0 +1,22 @@ +{ + "type": "object", + "properties" : { + "id": { "type": "integer" }, + "iid": { "type": "integer" }, + "project_id": { "type": ["integer", "null"] }, + "group_id": { "type": ["integer", "null"] }, + "title": { "type": "string" }, + "description": { "type": ["string", "null"] }, + "state": { "type": "string" }, + "created_at": { "type": "date" }, + "updated_at": { "type": "date" }, + "start_date": { "type": "date" }, + "due_date": { "type": "date" }, + "web_url": { "type": "string" } + }, + "required": [ + "id", "iid", "title", "description", "state", + "state", "created_at", "updated_at", "start_date", "due_date" + ], + "additionalProperties": false +} diff --git a/spec/fixtures/api/schemas/public_api/v4/milestones.json b/spec/fixtures/api/schemas/public_api/v4/milestones.json index 448e97d6c85..dcbc1910bfe 100644 --- a/spec/fixtures/api/schemas/public_api/v4/milestones.json +++ b/spec/fixtures/api/schemas/public_api/v4/milestones.json @@ -1,25 +1,6 @@ { "type": "array", "items": { - "type": "object", - "properties" : { - "id": { "type": "integer" }, - "iid": { "type": "integer" }, - "project_id": { "type": ["integer", "null"] }, - "group_id": { "type": ["integer", "null"] }, - "title": { "type": "string" }, - "description": { "type": ["string", "null"] }, - "state": { "type": "string" }, - "created_at": { "type": "date" }, - "updated_at": { "type": "date" }, - "start_date": { "type": "date" }, - "due_date": { "type": "date" }, - "web_url": { "type": "string" } - }, - "required": [ - "id", "iid", "title", "description", "state", - "state", "created_at", "updated_at", "start_date", "due_date" - ], - "additionalProperties": false + "$ref": "./milestone.json" } } diff --git a/spec/fixtures/api/schemas/release.json b/spec/fixtures/api/schemas/release.json new file mode 100644 index 00000000000..844405c3acd --- /dev/null +++ b/spec/fixtures/api/schemas/release.json @@ -0,0 +1,18 @@ +{ + "type": "object", + "required": ["name", "tag_name"], + "properties": { + "name": { "type": "string" }, + "tag_name": { "type": "string" }, + "description": { "type": "string" }, + "description_html": { "type": "string" }, + "created_at": { "type": "date" }, + "commit": { + "oneOf": [{ "type": "null" }, { "$ref": "public_api/v4/commit/basic.json" }] + }, + "author": { + "oneOf": [{ "type": "null" }, { "$ref": "public_api/v4/user/basic.json" }] + } + }, + "additionalProperties": false +} diff --git a/spec/fixtures/api/schemas/releases.json b/spec/fixtures/api/schemas/releases.json new file mode 100644 index 00000000000..e26215707fe --- /dev/null +++ b/spec/fixtures/api/schemas/releases.json @@ -0,0 +1,4 @@ +{ + "type": "array", + "items": { "$ref": "release.json" } +} diff --git a/spec/fixtures/gitlab/ci/external_files/.gitlab-ci-template-1.yml b/spec/fixtures/gitlab/ci/external_files/.gitlab-ci-template-1.yml index 0bab94a7c2e..1e88cd120aa 100644 --- a/spec/fixtures/gitlab/ci/external_files/.gitlab-ci-template-1.yml +++ b/spec/fixtures/gitlab/ci/external_files/.gitlab-ci-template-1.yml @@ -2,7 +2,6 @@ before_script: - apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs - ruby -v - which ruby - - gem install bundler --no-ri --no-rdoc - bundle install --jobs $(nproc) "${FLAGS[@]}" rspec: diff --git a/spec/fixtures/symlink_export.tar.gz b/spec/fixtures/symlink_export.tar.gz Binary files differnew file mode 100644 index 00000000000..f295f69c56c --- /dev/null +++ b/spec/fixtures/symlink_export.tar.gz diff --git a/spec/frontend/dummy_spec.js b/spec/frontend/dummy_spec.js deleted file mode 100644 index 2bfef25e9c6..00000000000 --- a/spec/frontend/dummy_spec.js +++ /dev/null @@ -1 +0,0 @@ -it('does nothing', () => {}); diff --git a/spec/javascripts/vue_shared/components/notes/timeline_entry_item_spec.js b/spec/frontend/vue_shared/components/notes/timeline_entry_item_spec.js index c15635f2105..c15635f2105 100644 --- a/spec/javascripts/vue_shared/components/notes/timeline_entry_item_spec.js +++ b/spec/frontend/vue_shared/components/notes/timeline_entry_item_spec.js diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb index 53c010fa0db..5396243f44d 100644 --- a/spec/helpers/diff_helper_spec.rb +++ b/spec/helpers/diff_helper_spec.rb @@ -256,43 +256,6 @@ describe DiffHelper do end end - context 'viewer related' do - let(:viewer) { diff_file.simple_viewer } - - before do - assign(:project, project) - end - - describe '#diff_render_error_reason' do - context 'for error :too_large' do - before do - expect(viewer).to receive(:render_error).and_return(:too_large) - end - - it 'returns an error message' do - expect(helper.diff_render_error_reason(viewer)).to eq('it is too large') - end - end - - context 'for error :server_side_but_stored_externally' do - before do - expect(viewer).to receive(:render_error).and_return(:server_side_but_stored_externally) - expect(diff_file).to receive(:external_storage).and_return(:lfs) - end - - it 'returns an error message' do - expect(helper.diff_render_error_reason(viewer)).to eq('it is stored in LFS') - end - end - end - - describe '#diff_render_error_options' do - it 'includes a "view the blob" link' do - expect(helper.diff_render_error_options(viewer)).to include(/view the blob/) - end - end - end - context '#diff_file_path_text' do it 'returns full path by default' do expect(diff_file_path_text(diff_file)).to eq(diff_file.new_path) diff --git a/spec/helpers/emails_helper_spec.rb b/spec/helpers/emails_helper_spec.rb index 139387e0b24..3820cf5cb9d 100644 --- a/spec/helpers/emails_helper_spec.rb +++ b/spec/helpers/emails_helper_spec.rb @@ -73,4 +73,59 @@ describe EmailsHelper do end end end + + describe '#create_list_id_string' do + using RSpec::Parameterized::TableSyntax + + where(:full_path, :list_id_path) do + "01234" | "01234" + "5/0123" | "012.." + "45/012" | "012.." + "012" | "012" + "23/01" | "01.23" + "2/01" | "01.2" + "234/01" | "01.." + "4/2/0" | "0.2.4" + "45/2/0" | "0.2.." + "5/23/0" | "0.." + "0-2/5" | "5.0-2" + "0_2/5" | "5.0-2" + "0.2/5" | "5.0-2" + end + + with_them do + it 'ellipcizes different variants' do + project = double("project") + allow(project).to receive(:full_path).and_return(full_path) + allow(project).to receive(:id).and_return(12345) + # Set a max length that gives only 5 chars for the project full path + max_length = "12345..#{Gitlab.config.gitlab.host}".length + 5 + list_id = create_list_id_string(project, max_length) + + expect(list_id).to eq("12345.#{list_id_path}.#{Gitlab.config.gitlab.host}") + expect(list_id).to satisfy { |s| s.length <= max_length } + end + end + end + + describe 'Create realistic List-Id identifier' do + using RSpec::Parameterized::TableSyntax + + where(:full_path, :list_id_path) do + "gitlab-org/gitlab-ce" | "gitlab-ce.gitlab-org" + "project-name/subproject_name/my.project" | "my-project.subproject-name.project-name" + end + + with_them do + it 'Produces the right List-Id' do + project = double("project") + allow(project).to receive(:full_path).and_return(full_path) + allow(project).to receive(:id).and_return(12345) + list_id = create_list_id_string(project) + + expect(list_id).to eq("12345.#{list_id_path}.#{Gitlab.config.gitlab.host}") + expect(list_id).to satisfy { |s| s.length <= 255 } + end + end + end end diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 4af98bc3678..81231cca085 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -43,16 +43,19 @@ describe IssuablesHelper do end describe '#issuable_labels_tooltip' do + let(:label_entity) { LabelEntity.represent(label).as_json } + let(:label2_entity) { LabelEntity.represent(label2).as_json } + it 'returns label text with no labels' do expect(issuable_labels_tooltip([])).to eq("Labels") end it 'returns label text with labels within max limit' do - expect(issuable_labels_tooltip([label])).to eq(label.title) + expect(issuable_labels_tooltip([label_entity])).to eq(label[:title]) end it 'returns label text with labels exceeding max limit' do - expect(issuable_labels_tooltip([label, label2], limit: 1)).to eq("#{label.title}, and 1 more") + expect(issuable_labels_tooltip([label_entity, label2_entity], limit: 1)).to eq("#{label[:title]}, and 1 more") end end @@ -197,33 +200,4 @@ describe IssuablesHelper do expect(helper.issuable_initial_data(issue)).to eq(expected_data) end end - - describe '#selected_labels' do - context 'if label_name param is a string' do - it 'returns a new label with title' do - allow(helper).to receive(:params) - .and_return(ActionController::Parameters.new(label_name: 'test label')) - - labels = helper.selected_labels - - expect(labels).to be_an(Array) - expect(labels.size).to eq(1) - expect(labels.first.title).to eq('test label') - end - end - - context 'if label_name param is an array' do - it 'returns a new label with title for each element' do - allow(helper).to receive(:params) - .and_return(ActionController::Parameters.new(label_name: ['test label 1', 'test label 2'])) - - labels = helper.selected_labels - - expect(labels).to be_an(Array) - expect(labels.size).to eq(2) - expect(labels.first.title).to eq('test label 1') - expect(labels.second.title).to eq('test label 2') - end - end - end end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 486416c3370..edd680ee1d1 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -519,4 +519,114 @@ describe ProjectsHelper do expect(helper.legacy_render_context({})).to be_empty end end + + describe '#explore_projects_tab?' do + subject { helper.explore_projects_tab? } + + it 'returns true when on the "All" tab under "Explore projects"' do + allow(@request).to receive(:path) { explore_projects_path } + + expect(subject).to be_truthy + end + + it 'returns true when on the "Trending" tab under "Explore projects"' do + allow(@request).to receive(:path) { trending_explore_projects_path } + + expect(subject).to be_truthy + end + + it 'returns true when on the "Starred" tab under "Explore projects"' do + allow(@request).to receive(:path) { starred_explore_projects_path } + + expect(subject).to be_truthy + end + + it 'returns false when on the "Your projects" tab' do + allow(@request).to receive(:path) { dashboard_projects_path } + + expect(subject).to be_falsey + end + end + + describe '#show_merge_request_count' do + context 'when the feature flag is enabled' do + before do + stub_feature_flags(project_list_show_mr_count: true) + end + + it 'returns true if compact mode is disabled' do + expect(helper.show_merge_request_count?).to be_truthy + end + + it 'returns false if compact mode is enabled' do + expect(helper.show_merge_request_count?(compact_mode: true)).to be_falsey + end + end + + context 'when the feature flag is disabled' do + before do + stub_feature_flags(project_list_show_mr_count: false) + end + + it 'always returns false' do + expect(helper.show_merge_request_count?(disabled: false)).to be_falsy + expect(helper.show_merge_request_count?(disabled: true)).to be_falsy + end + end + + context 'disabled flag' do + before do + stub_feature_flags(project_list_show_mr_count: true) + end + + it 'returns false if disabled flag is true' do + expect(helper.show_merge_request_count?(disabled: true)).to be_falsey + end + + it 'returns true if disabled flag is false' do + expect(helper.show_merge_request_count?).to be_truthy + end + end + end + + describe '#show_issue_count?' do + context 'when the feature flag is enabled' do + before do + stub_feature_flags(project_list_show_issue_count: true) + end + + it 'returns true if compact mode is disabled' do + expect(helper.show_issue_count?).to be_truthy + end + + it 'returns false if compact mode is enabled' do + expect(helper.show_issue_count?(compact_mode: true)).to be_falsey + end + end + + context 'when the feature flag is disabled' do + before do + stub_feature_flags(project_list_show_issue_count: false) + end + + it 'always returns false' do + expect(helper.show_issue_count?(disabled: false)).to be_falsy + expect(helper.show_issue_count?(disabled: true)).to be_falsy + end + end + + context 'disabled flag' do + before do + stub_feature_flags(project_list_show_issue_count: true) + end + + it 'returns false if disabled flag is true' do + expect(helper.show_issue_count?(disabled: true)).to be_falsey + end + + it 'returns true if disabled flag is false' do + expect(helper.show_issue_count?).to be_truthy + end + end + end end diff --git a/spec/helpers/sorting_helper_spec.rb b/spec/helpers/sorting_helper_spec.rb index cba0d93e144..f405268d198 100644 --- a/spec/helpers/sorting_helper_spec.rb +++ b/spec/helpers/sorting_helper_spec.rb @@ -21,7 +21,11 @@ describe SortingHelper do describe '#issuable_sort_direction_button' do before do - allow(self).to receive(:request).and_return(double(path: 'http://test.com', query_parameters: {})) + allow(self).to receive(:request).and_return(double(path: 'http://test.com', query_parameters: { label_name: 'test_label' })) + end + + it 'keeps label filter param' do + expect(issuable_sort_direction_button('created_date')).to include('label_name=test_label') end it 'returns icon with sort-highest when sort is created_date' do diff --git a/spec/helpers/storage_helper_spec.rb b/spec/helpers/storage_helper_spec.rb index c580b78c908..03df9deafa1 100644 --- a/spec/helpers/storage_helper_spec.rb +++ b/spec/helpers/storage_helper_spec.rb @@ -15,11 +15,7 @@ describe StorageHelper do end it "uses commas as thousands separator" do - if Gitlab.rails5? - expect(helper.storage_counter(100_000_000_000_000_000_000_000)).to eq("86,736.2 EB") - else - expect(helper.storage_counter(100_000_000_000_000_000)).to eq("90,949.5 TB") - end + expect(helper.storage_counter(100_000_000_000_000_000_000_000)).to eq("86,736.2 EB") end end end diff --git a/spec/helpers/version_check_helper_spec.rb b/spec/helpers/version_check_helper_spec.rb index 9d4e34abef5..bfec7ad4bba 100644 --- a/spec/helpers/version_check_helper_spec.rb +++ b/spec/helpers/version_check_helper_spec.rb @@ -13,21 +13,21 @@ describe VersionCheckHelper do before do allow(Rails.env).to receive(:production?) { true } allow(Gitlab::CurrentSettings.current_application_settings).to receive(:version_check_enabled) { true } - allow_any_instance_of(VersionCheck).to receive(:url) { 'https://version.host.com/check.svg?gitlab_info=xxx' } - - @image_tag = helper.version_status_badge + allow(VersionCheck).to receive(:url) { 'https://version.host.com/check.svg?gitlab_info=xxx' } end it 'should return an image tag' do - expect(@image_tag).to match(/^<img/) + expect(helper.version_status_badge).to start_with('<img') end it 'should have a js prefixed css class' do - expect(@image_tag).to match(/class="js-version-status-badge lazy"/) + expect(helper.version_status_badge) + .to match(/class="js-version-status-badge lazy"/) end it 'should have a VersionCheck url as the src' do - expect(@image_tag).to match(%r{src="https://version\.host\.com/check\.svg\?gitlab_info=xxx"}) + expect(helper.version_status_badge) + .to include(%{src="https://version.host.com/check.svg?gitlab_info=xxx"}) end end end diff --git a/spec/initializers/active_record_locking_spec.rb b/spec/initializers/active_record_locking_spec.rb new file mode 100644 index 00000000000..5a16aef78e6 --- /dev/null +++ b/spec/initializers/active_record_locking_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'ActiveRecord locking' do + let(:issue) { create(:issue) } + + shared_examples 'locked model' do + before do + issue.update_column(:lock_version, start_lock_version) + end + + it 'can be updated' do + issue.update(title: "New title") + + expect(issue.reload.lock_version).to eq(new_lock_version) + end + + it 'can be deleted' do + expect { issue.destroy }.to change { Issue.count }.by(-1) + end + end + + context 'when lock_version is NULL' do + let(:start_lock_version) { nil } + let(:new_lock_version) { 1 } + + it_behaves_like 'locked model' + end + + context 'when lock_version is 0' do + let(:start_lock_version) { 0 } + let(:new_lock_version) { 1 } + + it_behaves_like 'locked model' + end + + context 'when lock_version is 1' do + let(:start_lock_version) { 1 } + let(:new_lock_version) { 2 } + + it_behaves_like 'locked model' + end +end diff --git a/spec/initializers/lograge_spec.rb b/spec/initializers/lograge_spec.rb index af54a777373..24d366731a2 100644 --- a/spec/initializers/lograge_spec.rb +++ b/spec/initializers/lograge_spec.rb @@ -6,7 +6,7 @@ describe 'lograge', type: :request do let(:headers) { { 'X-Request-ID' => 'new-correlation-id' } } context 'for API requests' do - subject { get("/api/v4/endpoint", {}, headers) } + subject { get("/api/v4/endpoint", params: {}, headers: headers) } it 'logs to api_json log' do # we assert receiving parameters by grape logger @@ -19,7 +19,7 @@ describe 'lograge', type: :request do end context 'for Controller requests' do - subject { get("/", {}, headers) } + subject { get("/", params: {}, headers: headers) } it 'logs to production_json log' do # formatter receives a hash with correlation id diff --git a/spec/initializers/8_metrics_spec.rb b/spec/initializers/zz_metrics_spec.rb index 80c77057065..3eaccfe8d8b 100644 --- a/spec/initializers/8_metrics_spec.rb +++ b/spec/initializers/zz_metrics_spec.rb @@ -16,7 +16,7 @@ describe 'instrument_classes' do end it 'can autoload and instrument all files' do - require_relative '../../config/initializers/8_metrics' + require_relative '../../config/initializers/zz_metrics' expect { instrument_classes(config) }.not_to raise_error end end diff --git a/spec/javascripts/blob_edit/blob_bundle_spec.js b/spec/javascripts/blob_edit/blob_bundle_spec.js index 759d170af77..57f60a4a3dd 100644 --- a/spec/javascripts/blob_edit/blob_bundle_spec.js +++ b/spec/javascripts/blob_edit/blob_bundle_spec.js @@ -14,6 +14,7 @@ describe('EditBlob', () => { setFixtures(` <div class="js-edit-blob-form"> <button class="js-commit-button"></button> + <a class="btn btn-cancel" href="#"></a> </div>`); blobBundle(); }); @@ -27,4 +28,10 @@ describe('EditBlob', () => { expect(window.onbeforeunload).toBeNull(); }); + + it('removes beforeunload listener when cancel link is clicked', () => { + $('.btn.btn-cancel').click(); + + expect(window.onbeforeunload).toBeNull(); + }); }); diff --git a/spec/javascripts/boards/boards_store_spec.js b/spec/javascripts/boards/boards_store_spec.js index 54f1edfb1f9..22f192bc7f3 100644 --- a/spec/javascripts/boards/boards_store_spec.js +++ b/spec/javascripts/boards/boards_store_spec.js @@ -65,6 +65,13 @@ describe('Store', () => { expect(list).toBeDefined(); }); + it('finds list by label ID', () => { + boardsStore.addList(listObj); + const list = boardsStore.findListByLabelId(listObj.label.id); + + expect(list.id).toBe(listObj.id); + }); + it('gets issue when new list added', done => { boardsStore.addList(listObj); const list = boardsStore.findList('id', listObj.id); diff --git a/spec/javascripts/boards/components/issue_due_date_spec.js b/spec/javascripts/boards/components/issue_due_date_spec.js index 9e49330c052..054cf8c5b7d 100644 --- a/spec/javascripts/boards/components/issue_due_date_spec.js +++ b/spec/javascripts/boards/components/issue_due_date_spec.js @@ -49,10 +49,11 @@ describe('Issue Due Date component', () => { it('should render month and day for other dates', () => { date.setDate(date.getDate() + 17); vm = createComponent(date); + const today = new Date(); + const isDueInCurrentYear = today.getFullYear() === date.getFullYear(); + const format = isDueInCurrentYear ? 'mmm d' : 'mmm d, yyyy'; - expect(vm.$el.querySelector('time').textContent.trim()).toEqual( - dateFormat(date, 'mmm d', true), - ); + expect(vm.$el.querySelector('time').textContent.trim()).toEqual(dateFormat(date, format, true)); }); it('should contain the correct `.text-danger` css class for overdue issue', () => { diff --git a/spec/javascripts/boards/issue_spec.js b/spec/javascripts/boards/issue_spec.js index 437ab4bb3df..54fb0e8228b 100644 --- a/spec/javascripts/boards/issue_spec.js +++ b/spec/javascripts/boards/issue_spec.js @@ -55,15 +55,27 @@ describe('Issue model', () => { expect(issue.labels.length).toBe(2); }); - it('does not add existing label', () => { + it('does not add label if label id exists', () => { + issue.addLabel({ + id: 1, + title: 'test 2', + color: 'blue', + description: 'testing', + }); + + expect(issue.labels.length).toBe(1); + expect(issue.labels[0].color).toBe('red'); + }); + + it('adds other label with same title', () => { issue.addLabel({ id: 2, title: 'test', color: 'blue', - description: 'bugs!', + description: 'other test', }); - expect(issue.labels.length).toBe(1); + expect(issue.labels.length).toBe(2); }); it('finds label', () => { diff --git a/spec/javascripts/ci_variable_list/ci_variable_list_spec.js b/spec/javascripts/ci_variable_list/ci_variable_list_spec.js index 30b15011def..bef59b86d0c 100644 --- a/spec/javascripts/ci_variable_list/ci_variable_list_spec.js +++ b/spec/javascripts/ci_variable_list/ci_variable_list_spec.js @@ -118,6 +118,8 @@ describe('VariableList', () => { loadFixtures('projects/ci_cd_settings.html.raw'); $wrapper = $('.js-ci-variable-list-section'); + $wrapper.find('.js-ci-variable-input-protected').attr('data-default', 'false'); + variableList = new VariableList({ container: $wrapper, formField: 'variables', diff --git a/spec/javascripts/diffs/components/app_spec.js b/spec/javascripts/diffs/components/app_spec.js index 1e2f7ff4fd8..a2cbc0f3c72 100644 --- a/spec/javascripts/diffs/components/app_spec.js +++ b/spec/javascripts/diffs/components/app_spec.js @@ -1,33 +1,44 @@ -import Vue from 'vue'; -import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; +import Vuex from 'vuex'; +import { shallowMount, createLocalVue } from '@vue/test-utils'; import { TEST_HOST } from 'spec/test_constants'; import App from '~/diffs/components/app.vue'; +import NoChanges from '~/diffs/components/no_changes.vue'; +import DiffFile from '~/diffs/components/diff_file.vue'; import createDiffsStore from '../create_diffs_store'; describe('diffs/components/app', () => { const oldMrTabs = window.mrTabs; - const Component = Vue.extend(App); - + let store; let vm; - beforeEach(() => { - // setup globals (needed for component to mount :/) - window.mrTabs = jasmine.createSpyObj('mrTabs', ['resetViewContainer']); - window.mrTabs.expandViewContainer = jasmine.createSpy(); - window.location.hash = 'ABC_123'; + function createComponent(props = {}, extendStore = () => {}) { + const localVue = createLocalVue(); - // setup component - const store = createDiffsStore(); + localVue.use(Vuex); + + store = createDiffsStore(); store.state.diffs.isLoading = false; - vm = mountComponentWithStore(Component, { - store, - props: { + extendStore(store); + + vm = shallowMount(localVue.extend(App), { + localVue, + propsData: { endpoint: `${TEST_HOST}/diff/endpoint`, projectPath: 'namespace/project', currentUser: {}, + changesEmptyStateIllustration: '', + ...props, }, + store, }); + } + + beforeEach(() => { + // setup globals (needed for component to mount :/) + window.mrTabs = jasmine.createSpyObj('mrTabs', ['resetViewContainer']); + window.mrTabs.expandViewContainer = jasmine.createSpy(); + window.location.hash = 'ABC_123'; }); afterEach(() => { @@ -35,21 +46,53 @@ describe('diffs/components/app', () => { window.mrTabs = oldMrTabs; // reset component - vm.$destroy(); + vm.destroy(); }); it('does not show commit info', () => { - expect(vm.$el).not.toContainElement('.blob-commit-info'); + createComponent(); + + expect(vm.contains('.blob-commit-info')).toBe(false); }); it('sets highlighted row if hash exists in location object', done => { - vm.$props.shouldShow = true; - - vm.$nextTick() - .then(() => { - expect(vm.$store.state.diffs.highlightedRow).toBe('ABC_123'); - }) - .then(done) - .catch(done.fail); + createComponent({ + shouldShow: true, + }); + + // Component uses $nextTick so we wait until that has finished + setTimeout(() => { + expect(store.state.diffs.highlightedRow).toBe('ABC_123'); + + done(); + }); + }); + + describe('empty state', () => { + it('renders empty state when no diff files exist', () => { + createComponent(); + + expect(vm.contains(NoChanges)).toBe(true); + }); + + it('does not render empty state when diff files exist', () => { + createComponent({}, () => { + store.state.diffs.diffFiles.push({ + id: 1, + }); + }); + + expect(vm.contains(NoChanges)).toBe(false); + expect(vm.findAll(DiffFile).length).toBe(1); + }); + + it('does not render empty state when versions match', () => { + createComponent({}, () => { + store.state.diffs.startVersion = { version_index: 1 }; + store.state.diffs.mergeRequestDiff = { version_index: 1 }; + }); + + expect(vm.contains(NoChanges)).toBe(false); + }); }); }); diff --git a/spec/javascripts/diffs/components/diff_content_spec.js b/spec/javascripts/diffs/components/diff_content_spec.js index c25f6167163..9e158327a77 100644 --- a/spec/javascripts/diffs/components/diff_content_spec.js +++ b/spec/javascripts/diffs/components/diff_content_spec.js @@ -17,6 +17,7 @@ describe('DiffContent', () => { current_user: { can_create_note: false, }, + preview_note_path: 'path/to/preview', }; vm = mountComponentWithStore(Component, { @@ -49,6 +50,45 @@ describe('DiffContent', () => { }); }); + describe('empty files', () => { + beforeEach(() => { + vm.diffFile.empty = true; + vm.diffFile.highlighted_diff_lines = []; + vm.diffFile.parallel_diff_lines = []; + }); + + it('should render a message', done => { + vm.$nextTick(() => { + const block = vm.$el.querySelector('.diff-viewer .nothing-here-block'); + + expect(block).not.toBe(null); + expect(block.textContent.trim()).toContain('Empty file'); + + done(); + }); + }); + + it('should not render multiple messages', done => { + vm.diffFile.mode_changed = true; + vm.diffFile.b_mode = '100755'; + vm.diffFile.viewer.name = 'mode_changed'; + + vm.$nextTick(() => { + expect(vm.$el.querySelectorAll('.nothing-here-block').length).toBe(1); + + done(); + }); + }); + + it('should not render diff table', done => { + vm.$nextTick(() => { + expect(vm.$el.querySelector('table')).toBe(null); + + done(); + }); + }); + }); + describe('Non-Text diffs', () => { beforeEach(() => { vm.diffFile.viewer.name = 'image'; diff --git a/spec/javascripts/diffs/components/no_changes_spec.js b/spec/javascripts/diffs/components/no_changes_spec.js index 7237274eb43..e45d34bf9d5 100644 --- a/spec/javascripts/diffs/components/no_changes_spec.js +++ b/spec/javascripts/diffs/components/no_changes_spec.js @@ -1 +1,40 @@ -// TODO: https://gitlab.com/gitlab-org/gitlab-ce/issues/48034 +import { createLocalVue, shallowMount } from '@vue/test-utils'; +import Vuex from 'vuex'; +import { createStore } from '~/mr_notes/stores'; +import NoChanges from '~/diffs/components/no_changes.vue'; + +describe('Diff no changes empty state', () => { + let vm; + + function createComponent(extendStore = () => {}) { + const localVue = createLocalVue(); + localVue.use(Vuex); + + const store = createStore(); + extendStore(store); + + vm = shallowMount(localVue.extend(NoChanges), { + localVue, + store, + propsData: { + changesEmptyStateIllustration: '', + }, + }); + } + + afterEach(() => { + vm.destroy(); + }); + + it('prevents XSS', () => { + createComponent(store => { + // eslint-disable-next-line no-param-reassign + store.state.notes.noteableData = { + source_branch: '<script>alert("test");</script>', + target_branch: '<script>alert("test");</script>', + }; + }); + + expect(vm.contains('script')).toBe(false); + }); +}); diff --git a/spec/javascripts/diffs/mock_data/diff_discussions.js b/spec/javascripts/diffs/mock_data/diff_discussions.js index 44313caba29..c1e9f791925 100644 --- a/spec/javascripts/diffs/mock_data/diff_discussions.js +++ b/spec/javascripts/diffs/mock_data/diff_discussions.js @@ -487,8 +487,19 @@ export default { ], }, diff_discussion: true, - truncated_diff_lines: - '<tr class="line_holder new" id="">\n<td class="diff-line-num new old_line" data-linenumber="1">\n \n</td>\n<td class="diff-line-num new new_line" data-linenumber="1">\n1\n</td>\n<td class="line_content new noteable_line"><span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n</td>\n</tr>\n<tr class="line_holder new" id="">\n<td class="diff-line-num new old_line" data-linenumber="1">\n \n</td>\n<td class="diff-line-num new new_line" data-linenumber="2">\n2\n</td>\n<td class="line_content new noteable_line"><span id="LC2" class="line" lang="plaintext"></span>\n</td>\n</tr>\n', + truncated_diff_lines: [ + { + text: 'line', + rich_text: + '<tr class="line_holder new" id="">\n<td class="diff-line-num new old_line" data-linenumber="1">\n \n</td>\n<td class="diff-line-num new new_line" data-linenumber="1">\n1\n</td>\n<td class="line_content new noteable_line"><span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n</td>\n</tr>\n<tr class="line_holder new" id="">\n<td class="diff-line-num new old_line" data-linenumber="1">\n \n</td>\n<td class="diff-line-num new new_line" data-linenumber="2">\n2\n</td>\n<td class="line_content new noteable_line"><span id="LC2" class="line" lang="plaintext"></span>\n</td>\n</tr>\n', + can_receive_suggestion: true, + line_code: '6f209374f7e565f771b95720abf46024c41d1885_1_1', + type: 'new', + old_line: null, + new_line: 1, + meta_data: null, + }, + ], }; export const imageDiffDiscussions = [ diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/javascripts/diffs/store/mutations_spec.js index 23e8761bc55..d8733941181 100644 --- a/spec/javascripts/diffs/store/mutations_spec.js +++ b/spec/javascripts/diffs/store/mutations_spec.js @@ -277,6 +277,152 @@ describe('DiffsStoreMutations', () => { expect(state.diffFiles[0].highlighted_diff_lines[0].discussions[0].id).toEqual(1); }); + it('updates existing discussion', () => { + const diffPosition = { + base_sha: 'ed13df29948c41ba367caa757ab3ec4892509910', + head_sha: 'b921914f9a834ac47e6fd9420f78db0f83559130', + new_line: null, + new_path: '500-lines-4.txt', + old_line: 5, + old_path: '500-lines-4.txt', + start_sha: 'ed13df29948c41ba367caa757ab3ec4892509910', + }; + + const state = { + latestDiff: true, + diffFiles: [ + { + file_hash: 'ABC', + parallel_diff_lines: [ + { + left: { + line_code: 'ABC_1', + discussions: [], + }, + right: { + line_code: 'ABC_1', + discussions: [], + }, + }, + ], + highlighted_diff_lines: [ + { + line_code: 'ABC_1', + discussions: [], + }, + ], + }, + ], + }; + const discussion = { + id: 1, + line_code: 'ABC_1', + diff_discussion: true, + resolvable: true, + original_position: diffPosition, + position: diffPosition, + diff_file: { + file_hash: state.diffFiles[0].file_hash, + }, + }; + + const diffPositionByLineCode = { + ABC_1: diffPosition, + }; + + mutations[types.SET_LINE_DISCUSSIONS_FOR_FILE](state, { + discussion, + diffPositionByLineCode, + }); + + expect(state.diffFiles[0].parallel_diff_lines[0].left.discussions.length).toEqual(1); + expect(state.diffFiles[0].parallel_diff_lines[0].left.discussions[0].id).toEqual(1); + expect(state.diffFiles[0].parallel_diff_lines[0].right.discussions).toEqual([]); + + expect(state.diffFiles[0].highlighted_diff_lines[0].discussions.length).toEqual(1); + expect(state.diffFiles[0].highlighted_diff_lines[0].discussions[0].id).toEqual(1); + + mutations[types.SET_LINE_DISCUSSIONS_FOR_FILE](state, { + discussion: { + ...discussion, + resolved: true, + notes: ['test'], + }, + diffPositionByLineCode, + }); + + expect(state.diffFiles[0].parallel_diff_lines[0].left.discussions[0].notes.length).toBe(1); + expect(state.diffFiles[0].highlighted_diff_lines[0].discussions[0].notes.length).toBe(1); + + expect(state.diffFiles[0].parallel_diff_lines[0].left.discussions[0].resolved).toBe(true); + expect(state.diffFiles[0].highlighted_diff_lines[0].discussions[0].resolved).toBe(true); + }); + + it('should not duplicate inline diff discussions', () => { + const diffPosition = { + base_sha: 'ed13df29948c41ba367caa757ab3ec4892509910', + head_sha: 'b921914f9a834ac47e6fd9420f78db0f83559130', + new_line: null, + new_path: '500-lines-4.txt', + old_line: 5, + old_path: '500-lines-4.txt', + start_sha: 'ed13df29948c41ba367caa757ab3ec4892509910', + }; + + const state = { + latestDiff: true, + diffFiles: [ + { + file_hash: 'ABC', + highlighted_diff_lines: [ + { + line_code: 'ABC_1', + discussions: [ + { + id: 1, + line_code: 'ABC_1', + diff_discussion: true, + resolvable: true, + original_position: diffPosition, + position: diffPosition, + diff_file: { + file_hash: 'ABC', + }, + }, + ], + }, + { + line_code: 'ABC_2', + discussions: [], + }, + ], + }, + ], + }; + const discussion = { + id: 2, + line_code: 'ABC_2', + diff_discussion: true, + resolvable: true, + original_position: diffPosition, + position: diffPosition, + diff_file: { + file_hash: state.diffFiles[0].file_hash, + }, + }; + + const diffPositionByLineCode = { + ABC_2: diffPosition, + }; + + mutations[types.SET_LINE_DISCUSSIONS_FOR_FILE](state, { + discussion, + diffPositionByLineCode, + }); + + expect(state.diffFiles[0].highlighted_diff_lines[0].discussions.length).toBe(1); + }); + it('should add legacy discussions to the given line', () => { const diffPosition = { base_sha: 'ed13df29948c41ba367caa757ab3ec4892509910', @@ -356,10 +502,12 @@ describe('DiffsStoreMutations', () => { { id: 1, line_code: 'ABC_1', + notes: [], }, { id: 2, line_code: 'ABC_1', + notes: [], }, ], }, @@ -376,10 +524,12 @@ describe('DiffsStoreMutations', () => { { id: 1, line_code: 'ABC_1', + notes: [], }, { id: 2, line_code: 'ABC_1', + notes: [], }, ], }, diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/javascripts/diffs/store/utils_spec.js index f096638e3d6..4268634d302 100644 --- a/spec/javascripts/diffs/store/utils_spec.js +++ b/spec/javascripts/diffs/store/utils_spec.js @@ -294,10 +294,14 @@ describe('DiffsStoreUtils', () => { }); describe('prepareDiffData', () => { - it('sets the renderIt and collapsed attribute on files', () => { - const preparedDiff = { diff_files: [getDiffFileMock()] }; + let preparedDiff; + + beforeEach(() => { + preparedDiff = { diff_files: [getDiffFileMock()] }; utils.prepareDiffData(preparedDiff); + }); + it('sets the renderIt and collapsed attribute on files', () => { const firstParallelDiffLine = preparedDiff.diff_files[0].parallel_diff_lines[2]; expect(firstParallelDiffLine.left.discussions.length).toBe(0); @@ -323,6 +327,18 @@ describe('DiffsStoreUtils', () => { expect(preparedDiff.diff_files[0].renderIt).toBeTruthy(); expect(preparedDiff.diff_files[0].collapsed).toBeFalsy(); }); + + it('adds line_code to all lines', () => { + expect( + preparedDiff.diff_files[0].parallel_diff_lines.filter(line => !line.line_code), + ).toHaveLength(0); + }); + + it('uses right line code if left has none', () => { + const firstLine = preparedDiff.diff_files[0].parallel_diff_lines[0]; + + expect(firstLine.line_code).toEqual(firstLine.right.line_code); + }); }); describe('isDiscussionApplicableToLine', () => { diff --git a/spec/javascripts/environments/environment_terminal_button_spec.js b/spec/javascripts/environments/environment_terminal_button_spec.js index f1576b19d1b..56e18db59c5 100644 --- a/spec/javascripts/environments/environment_terminal_button_spec.js +++ b/spec/javascripts/environments/environment_terminal_button_spec.js @@ -2,30 +2,46 @@ import Vue from 'vue'; import terminalComp from '~/environments/components/environment_terminal_button.vue'; describe('Stop Component', () => { - let TerminalComponent; let component; const terminalPath = '/path'; - beforeEach(() => { - TerminalComponent = Vue.extend(terminalComp); - + const mountWithProps = props => { + const TerminalComponent = Vue.extend(terminalComp); component = new TerminalComponent({ - propsData: { - terminalPath, - }, + propsData: props, }).$mount(); - }); + }; + + describe('enabled', () => { + beforeEach(() => { + mountWithProps({ terminalPath }); + }); + + describe('computed', () => { + it('title', () => { + expect(component.title).toEqual('Terminal'); + }); + }); - describe('computed', () => { - it('title', () => { - expect(component.title).toEqual('Terminal'); + it('should render a link to open a web terminal with the provided path', () => { + expect(component.$el.tagName).toEqual('A'); + expect(component.$el.getAttribute('data-original-title')).toEqual('Terminal'); + expect(component.$el.getAttribute('aria-label')).toEqual('Terminal'); + expect(component.$el.getAttribute('href')).toEqual(terminalPath); + }); + + it('should render a non-disabled button', () => { + expect(component.$el.classList).not.toContain('disabled'); }); }); - it('should render a link to open a web terminal with the provided path', () => { - expect(component.$el.tagName).toEqual('A'); - expect(component.$el.getAttribute('data-original-title')).toEqual('Terminal'); - expect(component.$el.getAttribute('aria-label')).toEqual('Terminal'); - expect(component.$el.getAttribute('href')).toEqual(terminalPath); + describe('disabled', () => { + beforeEach(() => { + mountWithProps({ terminalPath, disabled: true }); + }); + + it('should render a disabled button', () => { + expect(component.$el.classList).toContain('disabled'); + }); }); }); diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js b/spec/javascripts/filtered_search/dropdown_utils_spec.js index 6605b0a30d7..cfd0b96ec43 100644 --- a/spec/javascripts/filtered_search/dropdown_utils_spec.js +++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js @@ -211,132 +211,6 @@ describe('Dropdown Utils', () => { }); }); - describe('mergeDuplicateLabels', () => { - const dataMap = { - label: { - title: 'label', - color: '#FFFFFF', - }, - }; - - it('should add label to dataMap if it is not a duplicate', () => { - const newLabel = { - title: 'new-label', - color: '#000000', - }; - - const updated = DropdownUtils.mergeDuplicateLabels(dataMap, newLabel); - - expect(updated[newLabel.title]).toEqual(newLabel); - }); - - it('should merge colors if label is a duplicate', () => { - const duplicate = { - title: 'label', - color: '#000000', - }; - - const updated = DropdownUtils.mergeDuplicateLabels(dataMap, duplicate); - - expect(updated.label.multipleColors).toEqual([dataMap.label.color, duplicate.color]); - }); - }); - - describe('duplicateLabelColor', () => { - it('should linear-gradient 2 colors', () => { - const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000']); - - expect(gradient).toEqual( - 'linear-gradient(#FFFFFF 0%, #FFFFFF 50%, #000000 50%, #000000 100%)', - ); - }); - - it('should linear-gradient 3 colors', () => { - const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333']); - - expect(gradient).toEqual( - 'linear-gradient(#FFFFFF 0%, #FFFFFF 33%, #000000 33%, #000000 66%, #333333 66%, #333333 100%)', - ); - }); - - it('should linear-gradient 4 colors', () => { - const gradient = DropdownUtils.duplicateLabelColor([ - '#FFFFFF', - '#000000', - '#333333', - '#DDDDDD', - ]); - - expect(gradient).toEqual( - 'linear-gradient(#FFFFFF 0%, #FFFFFF 25%, #000000 25%, #000000 50%, #333333 50%, #333333 75%, #DDDDDD 75%, #DDDDDD 100%)', - ); - }); - - it('should not linear-gradient more than 4 colors', () => { - const gradient = DropdownUtils.duplicateLabelColor([ - '#FFFFFF', - '#000000', - '#333333', - '#DDDDDD', - '#EEEEEE', - ]); - - expect(gradient.indexOf('#EEEEEE')).toBe(-1); - }); - }); - - describe('duplicateLabelPreprocessing', () => { - it('should set preprocessed to true', () => { - const results = DropdownUtils.duplicateLabelPreprocessing([]); - - expect(results.preprocessed).toEqual(true); - }); - - it('should not mutate existing data if there are no duplicates', () => { - const data = [ - { - title: 'label1', - color: '#FFFFFF', - }, - { - title: 'label2', - color: '#000000', - }, - ]; - const results = DropdownUtils.duplicateLabelPreprocessing(data); - - expect(results.length).toEqual(2); - expect(results[0]).toEqual(data[0]); - expect(results[1]).toEqual(data[1]); - }); - - describe('duplicate labels', () => { - const data = [ - { - title: 'label', - color: '#FFFFFF', - }, - { - title: 'label', - color: '#000000', - }, - ]; - const results = DropdownUtils.duplicateLabelPreprocessing(data); - - it('should merge duplicate labels', () => { - expect(results.length).toEqual(1); - }); - - it('should convert multiple colored labels into linear-gradient', () => { - expect(results[0].color).toEqual(DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000'])); - }); - - it('should set multiple colored label text color to black', () => { - expect(results[0].text_color).toEqual('#000000'); - }); - }); - }); - describe('setDataValueIfSelected', () => { beforeEach(() => { spyOn(FilteredSearchDropdownManager, 'addWordToInput').and.callFake(() => {}); diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js index 4f561df7943..9aa3cbaa231 100644 --- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js @@ -909,16 +909,6 @@ describe('Filtered Search Visual Tokens', () => { expect(token.style.backgroundColor).not.toEqual(originalBackgroundColor); }); - it('should not set backgroundColor when it is a linear-gradient', () => { - const token = subject.setTokenStyle( - bugLabelToken, - 'linear-gradient(135deg, red, blue)', - 'white', - ); - - expect(token.style.backgroundColor).toEqual(bugLabelToken.style.backgroundColor); - }); - it('should set textColor', () => { const token = subject.setTokenStyle(bugLabelToken, 'white', 'black'); @@ -935,39 +925,6 @@ describe('Filtered Search Visual Tokens', () => { }); }); - describe('preprocessLabel', () => { - const endpoint = 'endpoint'; - - it('does not preprocess more than once', () => { - let labels = []; - - spyOn(DropdownUtils, 'duplicateLabelPreprocessing').and.callFake(() => []); - - labels = FilteredSearchVisualTokens.preprocessLabel(endpoint, labels); - FilteredSearchVisualTokens.preprocessLabel(endpoint, labels); - - expect(DropdownUtils.duplicateLabelPreprocessing.calls.count()).toEqual(1); - }); - - describe('not preprocessed before', () => { - it('returns preprocessed labels', () => { - let labels = []; - - expect(labels.preprocessed).not.toEqual(true); - labels = FilteredSearchVisualTokens.preprocessLabel(endpoint, labels); - - expect(labels.preprocessed).toEqual(true); - }); - - it('overrides AjaxCache with preprocessed results', () => { - spyOn(AjaxCache, 'override').and.callFake(() => {}); - FilteredSearchVisualTokens.preprocessLabel(endpoint, []); - - expect(AjaxCache.override.calls.count()).toEqual(1); - }); - }); - }); - describe('updateLabelTokenColor', () => { const jsonFixtureName = 'labels/project_labels.json'; const dummyEndpoint = '/dummy/endpoint'; diff --git a/spec/javascripts/fixtures/blob.rb b/spec/javascripts/fixtures/blob.rb index 81e8a51a902..1b2a3b484bb 100644 --- a/spec/javascripts/fixtures/blob.rb +++ b/spec/javascripts/fixtures/blob.rb @@ -22,10 +22,11 @@ describe Projects::BlobController, '(JavaScript fixtures)', type: :controller do end it 'blob/show.html.raw' do |example| - get(:show, - namespace_id: project.namespace, - project_id: project, - id: 'add-ipython-files/files/ipython/basic.ipynb') + get(:show, params: { + namespace_id: project.namespace, + project_id: project, + id: 'add-ipython-files/files/ipython/basic.ipynb' + }) expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/boards.rb b/spec/javascripts/fixtures/boards.rb index 494c9cabdcc..1d675e008ba 100644 --- a/spec/javascripts/fixtures/boards.rb +++ b/spec/javascripts/fixtures/boards.rb @@ -18,9 +18,10 @@ describe Projects::BoardsController, '(JavaScript fixtures)', type: :controller end it 'boards/show.html.raw' do |example| - get(:index, - namespace_id: project.namespace, - project_id: project) + get(:index, params: { + namespace_id: project.namespace, + project_id: project + }) expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/branches.rb b/spec/javascripts/fixtures/branches.rb index 4fc072d2585..3cc713ef90f 100644 --- a/spec/javascripts/fixtures/branches.rb +++ b/spec/javascripts/fixtures/branches.rb @@ -22,9 +22,10 @@ describe Projects::BranchesController, '(JavaScript fixtures)', type: :controlle end it 'branches/new_branch.html.raw' do |example| - get :new, + get :new, params: { namespace_id: project.namespace.to_param, project_id: project + } expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/clusters.rb b/spec/javascripts/fixtures/clusters.rb index 8e74c4f859c..69dbe54ffc2 100644 --- a/spec/javascripts/fixtures/clusters.rb +++ b/spec/javascripts/fixtures/clusters.rb @@ -23,10 +23,11 @@ describe Projects::ClustersController, '(JavaScript fixtures)', type: :controlle end it 'clusters/show_cluster.html.raw' do |example| - get :show, + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, id: cluster + } expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/commit.rb b/spec/javascripts/fixtures/commit.rb index 24ab8159a18..f0e4bb50c67 100644 --- a/spec/javascripts/fixtures/commit.rb +++ b/spec/javascripts/fixtures/commit.rb @@ -25,7 +25,7 @@ describe Projects::CommitController, '(JavaScript fixtures)', type: :controller id: commit.id } - get :show, params + get :show, params: params expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/deploy_keys.rb b/spec/javascripts/fixtures/deploy_keys.rb index 24699c3043a..efbda955972 100644 --- a/spec/javascripts/fixtures/deploy_keys.rb +++ b/spec/javascripts/fixtures/deploy_keys.rb @@ -33,10 +33,10 @@ describe Projects::DeployKeysController, '(JavaScript fixtures)', type: :control create(:deploy_keys_project, project: project3, deploy_key: project_key) create(:deploy_keys_project, project: project4, deploy_key: project_key) - get :index, + get :index, params: { namespace_id: project.namespace.to_param, - project_id: project, - format: :json + project_id: project + }, format: :json expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/groups.rb b/spec/javascripts/fixtures/groups.rb index b42f442557c..f8d55fc97c3 100644 --- a/spec/javascripts/fixtures/groups.rb +++ b/spec/javascripts/fixtures/groups.rb @@ -19,8 +19,7 @@ describe 'Groups (JavaScript fixtures)', type: :controller do describe GroupsController, '(JavaScript fixtures)', type: :controller do it 'groups/edit.html.raw' do |example| - get :edit, - id: group + get :edit, params: { id: group } expect(response).to be_success store_frontend_fixture(response, example.description) @@ -29,8 +28,7 @@ describe 'Groups (JavaScript fixtures)', type: :controller do describe Groups::Settings::CiCdController, '(JavaScript fixtures)', type: :controller do it 'groups/ci_cd_settings.html.raw' do |example| - get :show, - group_id: group + get :show, params: { group_id: group } expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/issues.rb b/spec/javascripts/fixtures/issues.rb index 0ee2f82dfd6..18fb1bebf8b 100644 --- a/spec/javascripts/fixtures/issues.rb +++ b/spec/javascripts/fixtures/issues.rb @@ -43,9 +43,10 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller it 'issues/issue_list.html.raw' do |example| create(:issue, project: project) - get :index, + get :index, params: { namespace_id: project.namespace.to_param, project_id: project + } expect(response).to be_success store_frontend_fixture(response, example.description) @@ -54,10 +55,11 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller private def render_issue(fixture_file_name, issue) - get :show, + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, id: issue.to_param + } expect(response).to be_success store_frontend_fixture(response, fixture_file_name) diff --git a/spec/javascripts/fixtures/jobs.rb b/spec/javascripts/fixtures/jobs.rb index 82d7a5e394e..d6b5349594d 100644 --- a/spec/javascripts/fixtures/jobs.rb +++ b/spec/javascripts/fixtures/jobs.rb @@ -34,21 +34,22 @@ describe Projects::JobsController, '(JavaScript fixtures)', type: :controller do end it 'builds/build-with-artifacts.html.raw' do |example| - get :show, + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, id: build_with_artifacts.to_param + } expect(response).to be_success store_frontend_fixture(response, example.description) end it 'jobs/delayed.json' do |example| - get :show, - namespace_id: project.namespace.to_param, - project_id: project, - id: delayed_job.to_param, - format: :json + get :show, params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: delayed_job.to_param + }, format: :json expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/labels.rb b/spec/javascripts/fixtures/labels.rb index b730d557e21..9420194e675 100644 --- a/spec/javascripts/fixtures/labels.rb +++ b/spec/javascripts/fixtures/labels.rb @@ -31,9 +31,9 @@ describe 'Labels (JavaScript fixtures)' do end it 'labels/group_labels.json' do |example| - get :index, - group_id: group, - format: 'json' + get :index, params: { + group_id: group + }, format: 'json' expect(response).to be_success store_frontend_fixture(response, example.description) @@ -48,10 +48,10 @@ describe 'Labels (JavaScript fixtures)' do end it 'labels/project_labels.json' do |example| - get :index, + get :index, params: { namespace_id: group, - project_id: project, - format: 'json' + project_id: project + }, format: 'json' expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/merge_requests.rb b/spec/javascripts/fixtures/merge_requests.rb index 7257d0c8556..26e81f06c0b 100644 --- a/spec/javascripts/fixtures/merge_requests.rb +++ b/spec/javascripts/fixtures/merge_requests.rb @@ -112,21 +112,21 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont private def render_discussions_json(merge_request, fixture_file_name) - get :discussions, + get :discussions, params: { namespace_id: project.namespace.to_param, project_id: project, - id: merge_request.to_param, - format: :json + id: merge_request.to_param + }, format: :json store_frontend_fixture(response, fixture_file_name) end def render_merge_request(fixture_file_name, merge_request) - get :show, + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, - id: merge_request.to_param, - format: :html + id: merge_request.to_param + }, format: :html expect(response).to be_success store_frontend_fixture(response, fixture_file_name) diff --git a/spec/javascripts/fixtures/merge_requests_diffs.rb b/spec/javascripts/fixtures/merge_requests_diffs.rb index afe34b834b0..57462e74bb2 100644 --- a/spec/javascripts/fixtures/merge_requests_diffs.rb +++ b/spec/javascripts/fixtures/merge_requests_diffs.rb @@ -57,13 +57,13 @@ describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type private def render_merge_request(fixture_file_name, merge_request, view: 'inline', **extra_params) - get :show, + get :show, params: { namespace_id: project.namespace.to_param, project_id: project, id: merge_request.to_param, - format: :json, view: view, **extra_params + }, format: :json expect(response).to be_success store_frontend_fixture(response, fixture_file_name) diff --git a/spec/javascripts/fixtures/pipeline_schedules.rb b/spec/javascripts/fixtures/pipeline_schedules.rb index 56f27ea7df1..05d79ec8de9 100644 --- a/spec/javascripts/fixtures/pipeline_schedules.rb +++ b/spec/javascripts/fixtures/pipeline_schedules.rb @@ -22,20 +22,22 @@ describe Projects::PipelineSchedulesController, '(JavaScript fixtures)', type: : end it 'pipeline_schedules/edit.html.raw' do |example| - get :edit, + get :edit, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + } expect(response).to be_success store_frontend_fixture(response, example.description) end it 'pipeline_schedules/edit_with_variables.html.raw' do |example| - get :edit, + get :edit, params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule_populated.id + } expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/pipelines.rb b/spec/javascripts/fixtures/pipelines.rb index bb85da50f0f..42b552e81c0 100644 --- a/spec/javascripts/fixtures/pipelines.rb +++ b/spec/javascripts/fixtures/pipelines.rb @@ -24,10 +24,10 @@ describe Projects::PipelinesController, '(JavaScript fixtures)', type: :controll end it 'pipelines/pipelines.json' do |example| - get :index, + get :index, params: { namespace_id: namespace, - project_id: project, - format: :json + project_id: project + }, format: :json expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/projects.rb b/spec/javascripts/fixtures/projects.rb index d98f7f55b20..9b48646f8f0 100644 --- a/spec/javascripts/fixtures/projects.rb +++ b/spec/javascripts/fixtures/projects.rb @@ -28,27 +28,30 @@ describe 'Projects (JavaScript fixtures)', type: :controller do describe ProjectsController, '(JavaScript fixtures)', type: :controller do it 'projects/dashboard.html.raw' do |example| - get :show, + get :show, params: { namespace_id: project.namespace.to_param, id: project + } expect(response).to be_success store_frontend_fixture(response, example.description) end it 'projects/overview.html.raw' do |example| - get :show, + get :show, params: { namespace_id: project_with_repo.namespace.to_param, id: project_with_repo + } expect(response).to be_success store_frontend_fixture(response, example.description) end it 'projects/edit.html.raw' do |example| - get :edit, + get :edit, params: { namespace_id: project.namespace.to_param, id: project + } expect(response).to be_success store_frontend_fixture(response, example.description) @@ -57,18 +60,20 @@ describe 'Projects (JavaScript fixtures)', type: :controller do describe Projects::Settings::CiCdController, '(JavaScript fixtures)', type: :controller do it 'projects/ci_cd_settings.html.raw' do |example| - get :show, + get :show, params: { namespace_id: project.namespace.to_param, project_id: project + } expect(response).to be_success store_frontend_fixture(response, example.description) end it 'projects/ci_cd_settings_with_variables.html.raw' do |example| - get :show, + get :show, params: { namespace_id: project_variable_populated.namespace.to_param, project_id: project_variable_populated + } expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/prometheus_service.rb b/spec/javascripts/fixtures/prometheus_service.rb index f95f8038ffb..746fbfd66dd 100644 --- a/spec/javascripts/fixtures/prometheus_service.rb +++ b/spec/javascripts/fixtures/prometheus_service.rb @@ -23,10 +23,11 @@ describe Projects::ServicesController, '(JavaScript fixtures)', type: :controlle end it 'services/prometheus/prometheus_service.html.raw' do |example| - get :edit, + get :edit, params: { namespace_id: namespace, project_id: project, id: service.to_param + } expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/services.rb b/spec/javascripts/fixtures/services.rb index 9280ed5a7f1..6ccd74a07ff 100644 --- a/spec/javascripts/fixtures/services.rb +++ b/spec/javascripts/fixtures/services.rb @@ -23,10 +23,11 @@ describe Projects::ServicesController, '(JavaScript fixtures)', type: :controlle end it 'services/edit_service.html.raw' do |example| - get :edit, + get :edit, params: { namespace_id: namespace, project_id: project, id: service.to_param + } expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/snippet.rb b/spec/javascripts/fixtures/snippet.rb index 38fc963caf7..a14837e4d4a 100644 --- a/spec/javascripts/fixtures/snippet.rb +++ b/spec/javascripts/fixtures/snippet.rb @@ -24,7 +24,7 @@ describe SnippetsController, '(JavaScript fixtures)', type: :controller do end it 'snippets/show.html.raw' do |example| - get(:show, id: snippet.to_param) + get(:show, params: { id: snippet.to_param }) expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/todos.rb b/spec/javascripts/fixtures/todos.rb index 426b854fe8b..b5f6620873b 100644 --- a/spec/javascripts/fixtures/todos.rb +++ b/spec/javascripts/fixtures/todos.rb @@ -42,12 +42,12 @@ describe 'Todos (JavaScript fixtures)' do end it 'todos/todos.json' do |example| - post :create, + post :create, params: { namespace_id: namespace, project_id: project, issuable_type: 'issue', - issuable_id: issue_2.id, - format: 'json' + issuable_id: issue_2.id + }, format: 'json' expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/fixtures/u2f.rb b/spec/javascripts/fixtures/u2f.rb index e3d7986f2cf..f0aa874bf75 100644 --- a/spec/javascripts/fixtures/u2f.rb +++ b/spec/javascripts/fixtures/u2f.rb @@ -21,7 +21,7 @@ context 'U2F' do it 'u2f/authenticate.html.raw' do |example| allow(controller).to receive(:find_user).and_return(user) - post :create, user: { login: user.username, password: user.password } + post :create, params: { user: { login: user.username, password: user.password } } expect(response).to be_success store_frontend_fixture(response, example.description) diff --git a/spec/javascripts/jobs/components/artifacts_block_spec.js b/spec/javascripts/jobs/components/artifacts_block_spec.js index 2fa7ff653fe..27d480ef2ea 100644 --- a/spec/javascripts/jobs/components/artifacts_block_spec.js +++ b/spec/javascripts/jobs/components/artifacts_block_spec.js @@ -2,6 +2,7 @@ import Vue from 'vue'; import { getTimeago } from '~/lib/utils/datetime_utility'; import component from '~/jobs/components/artifacts_block.vue'; import mountComponent from '../../helpers/vue_mount_component_helper'; +import { trimText } from '../../helpers/vue_component_helper'; describe('Artifacts block', () => { const Component = Vue.extend(component); @@ -9,7 +10,7 @@ describe('Artifacts block', () => { const expireAt = '2018-08-14T09:38:49.157Z'; const timeago = getTimeago(); - const formatedDate = timeago.format(expireAt); + const formattedDate = timeago.format(expireAt); const expiredArtifact = { expire_at: expireAt, @@ -36,9 +37,8 @@ describe('Artifacts block', () => { expect(vm.$el.querySelector('.js-artifacts-removed')).not.toBeNull(); expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).toBeNull(); - expect(vm.$el.textContent).toContain(formatedDate); - expect(vm.$el.querySelector('.js-artifacts-removed').textContent.trim()).toEqual( - 'The artifacts were removed', + expect(trimText(vm.$el.querySelector('.js-artifacts-removed').textContent)).toEqual( + `The artifacts were removed ${formattedDate}`, ); }); }); @@ -51,9 +51,8 @@ describe('Artifacts block', () => { expect(vm.$el.querySelector('.js-artifacts-removed')).toBeNull(); expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).not.toBeNull(); - expect(vm.$el.textContent).toContain(formatedDate); - expect(vm.$el.querySelector('.js-artifacts-will-be-removed').textContent.trim()).toEqual( - 'The artifacts will be removed in', + expect(trimText(vm.$el.querySelector('.js-artifacts-will-be-removed').textContent)).toEqual( + `The artifacts will be removed ${formattedDate}`, ); }); }); diff --git a/spec/javascripts/jobs/components/sidebar_spec.js b/spec/javascripts/jobs/components/sidebar_spec.js index 424092d2d88..b0bc16d7c64 100644 --- a/spec/javascripts/jobs/components/sidebar_spec.js +++ b/spec/javascripts/jobs/components/sidebar_spec.js @@ -79,14 +79,6 @@ describe('Sidebar details block', () => { }); describe('information', () => { - it('should render merge request link', () => { - expect(trimText(vm.$el.querySelector('.js-job-mr').textContent)).toEqual('Merge Request: !2'); - - expect(vm.$el.querySelector('.js-job-mr a').getAttribute('href')).toEqual( - job.merge_request.path, - ); - }); - it('should render job duration', () => { expect(trimText(vm.$el.querySelector('.js-job-duration').textContent)).toEqual( 'Duration: 6 seconds', diff --git a/spec/javascripts/notes/components/note_app_spec.js b/spec/javascripts/notes/components/note_app_spec.js index 0081f42c330..22bee049f9c 100644 --- a/spec/javascripts/notes/components/note_app_spec.js +++ b/spec/javascripts/notes/components/note_app_spec.js @@ -30,6 +30,8 @@ describe('note_app', () => { jasmine.addMatchers(vueMatchers); $('body').attr('data-page', 'projects:merge_requests:show'); + setFixtures('<div class="js-vue-notes-event"><div id="app"></div></div>'); + const IssueNotesApp = Vue.extend(notesApp); store = createStore(); @@ -43,6 +45,7 @@ describe('note_app', () => { return mountComponentWithStore(IssueNotesApp, { props, store, + el: document.getElementById('app'), }); }; }); @@ -283,4 +286,24 @@ describe('note_app', () => { }, 0); }); }); + + describe('emoji awards', () => { + it('dispatches toggleAward after toggleAward event', () => { + const toggleAwardEvent = new CustomEvent('toggleAward', { + detail: { + awardName: 'test', + noteId: 1, + }, + }); + + spyOn(vm.$store, 'dispatch'); + + vm.$el.parentElement.dispatchEvent(toggleAwardEvent); + + expect(vm.$store.dispatch).toHaveBeenCalledWith('toggleAward', { + awardName: 'test', + noteId: 1, + }); + }); + }); }); diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js index 106a4ac2546..3aff2dd0641 100644 --- a/spec/javascripts/notes/components/noteable_discussion_spec.js +++ b/spec/javascripts/notes/components/noteable_discussion_spec.js @@ -133,8 +133,10 @@ describe('noteable_discussion component', () => { }); }); - describe('commit discussion', () => { + describe('action text', () => { const commitId = 'razupaltuff'; + const truncatedCommitId = commitId.substr(0, 8); + let commitElement; beforeEach(() => { vm.$destroy(); @@ -143,7 +145,6 @@ describe('noteable_discussion component', () => { projectPath: 'something', }; - vm.$destroy(); vm = new Component({ propsData: { discussion: { @@ -159,17 +160,73 @@ describe('noteable_discussion component', () => { }, store, }).$mount(); + + commitElement = vm.$el.querySelector('.commit-sha'); + }); + + describe('for commit discussions', () => { + it('should display a monospace started a discussion on commit', () => { + expect(vm.$el).toContainText(`started a discussion on commit ${truncatedCommitId}`); + expect(commitElement).not.toBe(null); + expect(commitElement).toHaveText(truncatedCommitId); + }); }); - it('displays a monospace started a discussion on commit', () => { - const truncatedCommitId = commitId.substr(0, 8); + describe('for diff discussion with a commit id', () => { + it('should display started discussion on commit header', done => { + vm.discussion.for_commit = false; - expect(vm.$el).toContainText(`started a discussion on commit ${truncatedCommitId}`); + vm.$nextTick(() => { + expect(vm.$el).toContainText(`started a discussion on commit ${truncatedCommitId}`); + expect(commitElement).not.toBe(null); - const commitElement = vm.$el.querySelector('.commit-sha'); + done(); + }); + }); - expect(commitElement).not.toBe(null); - expect(commitElement).toHaveText(truncatedCommitId); + it('should display outdated change on commit header', done => { + vm.discussion.for_commit = false; + vm.discussion.active = false; + + vm.$nextTick(() => { + expect(vm.$el).toContainText( + `started a discussion on an outdated change in commit ${truncatedCommitId}`, + ); + + expect(commitElement).not.toBe(null); + + done(); + }); + }); + }); + + describe('for diff discussions without a commit id', () => { + it('should show started a discussion on the diff text', done => { + Object.assign(vm.discussion, { + for_commit: false, + commit_id: null, + }); + + vm.$nextTick(() => { + expect(vm.$el).toContainText('started a discussion on the diff'); + + done(); + }); + }); + + it('should show discussion on older version text', done => { + Object.assign(vm.discussion, { + for_commit: false, + commit_id: null, + active: false, + }); + + vm.$nextTick(() => { + expect(vm.$el).toContainText('started a discussion on an old version of the diff'); + + done(); + }); + }); }); }); }); diff --git a/spec/javascripts/releases/components/app_spec.js b/spec/javascripts/releases/components/app_spec.js new file mode 100644 index 00000000000..f30c7685e34 --- /dev/null +++ b/spec/javascripts/releases/components/app_spec.js @@ -0,0 +1,79 @@ +import Vue from 'vue'; +import app from '~/releases/components/app.vue'; +import createStore from '~/releases/store'; +import api from '~/api'; +import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; +import { resetStore } from '../store/helpers'; +import { releases } from '../mock_data'; + +describe('Releases App ', () => { + const Component = Vue.extend(app); + let store; + let vm; + + const props = { + projectId: 'gitlab-ce', + documentationLink: 'help/releases', + illustrationPath: 'illustration/path', + }; + + beforeEach(() => { + store = createStore(); + }); + + afterEach(() => { + resetStore(store); + vm.$destroy(); + }); + + describe('while loading', () => { + beforeEach(() => { + spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: [] })); + vm = mountComponentWithStore(Component, { props, store }); + }); + + it('renders loading icon', done => { + expect(vm.$el.querySelector('.js-loading')).not.toBeNull(); + expect(vm.$el.querySelector('.js-empty-state')).toBeNull(); + expect(vm.$el.querySelector('.js-success-state')).toBeNull(); + + setTimeout(() => { + done(); + }, 0); + }); + }); + + describe('with successful request', () => { + beforeEach(() => { + spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: releases })); + vm = mountComponentWithStore(Component, { props, store }); + }); + + it('renders success state', done => { + setTimeout(() => { + expect(vm.$el.querySelector('.js-loading')).toBeNull(); + expect(vm.$el.querySelector('.js-empty-state')).toBeNull(); + expect(vm.$el.querySelector('.js-success-state')).not.toBeNull(); + + done(); + }, 0); + }); + }); + + describe('with empty request', () => { + beforeEach(() => { + spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: [] })); + vm = mountComponentWithStore(Component, { props, store }); + }); + + it('renders empty state', done => { + setTimeout(() => { + expect(vm.$el.querySelector('.js-loading')).toBeNull(); + expect(vm.$el.querySelector('.js-empty-state')).not.toBeNull(); + expect(vm.$el.querySelector('.js-success-state')).toBeNull(); + + done(); + }, 0); + }); + }); +}); diff --git a/spec/javascripts/releases/components/release_block_spec.js b/spec/javascripts/releases/components/release_block_spec.js new file mode 100644 index 00000000000..29420216bc4 --- /dev/null +++ b/spec/javascripts/releases/components/release_block_spec.js @@ -0,0 +1,136 @@ +import Vue from 'vue'; +import component from '~/releases/components/release_block.vue'; +import timeagoMixin from '~/vue_shared/mixins/timeago'; + +import mountComponent from '../../helpers/vue_mount_component_helper'; + +describe('Release block', () => { + const Component = Vue.extend(component); + + const release = { + name: 'Bionic Beaver', + tag_name: '18.04', + description: '## changelog\n\n* line 1\n* line2', + description_html: '<div><h2>changelog</h2><ul><li>line1</li<li>line 2</li></ul></div>', + author_name: 'Release bot', + author_email: 'release-bot@example.com', + created_at: '2012-05-28T05:00:00-07:00', + author: { + avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png', + id: 482476, + name: 'John Doe', + path: '/johndoe', + state: 'active', + status_tooltip_html: null, + username: 'johndoe', + web_url: 'https://gitlab.com/johndoe', + }, + commit: { + id: '2695effb5807a22ff3d138d593fd856244e155e7', + short_id: '2695effb', + title: 'Initial commit', + created_at: '2017-07-26T11:08:53.000+02:00', + parent_ids: ['2a4b78934375d7f53875269ffd4f45fd83a84ebe'], + message: 'Initial commit', + author_name: 'John Smith', + author_email: 'john@example.com', + authored_date: '2012-05-28T04:42:42-07:00', + committer_name: 'Jack Smith', + committer_email: 'jack@example.com', + committed_date: '2012-05-28T04:42:42-07:00', + }, + assets: { + count: 6, + sources: [ + { + format: 'zip', + url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.zip', + }, + { + format: 'tar.gz', + url: + 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.gz', + }, + { + format: 'tar.bz2', + url: + 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.bz2', + }, + { + format: 'tar', + url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar', + }, + ], + links: [ + { + name: 'release-18.04.dmg', + url: 'https://my-external-hosting.example.com/scrambled-url/', + external: true, + }, + { + name: 'binary-linux-amd64', + url: + 'https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50', + external: false, + }, + ], + }, + }; + let vm; + + beforeEach(() => { + vm = mountComponent(Component, { release }); + }); + + afterEach(() => { + vm.$destroy(); + }); + + it('renders release name', () => { + expect(vm.$el.textContent).toContain(release.name); + }); + + it('renders commit sha', () => { + expect(vm.$el.textContent).toContain(release.commit.short_id); + }); + + it('renders tag name', () => { + expect(vm.$el.textContent).toContain(release.tag_name); + }); + + it('renders release date', () => { + expect(vm.$el.textContent).toContain(timeagoMixin.methods.timeFormated(release.created_at)); + }); + + it('renders number of assets provided', () => { + expect(vm.$el.querySelector('.js-assets-count').textContent).toContain(release.assets.count); + }); + + it('renders dropdown with the sources', () => { + expect(vm.$el.querySelectorAll('.js-sources-dropdown li').length).toEqual( + release.assets.sources.length, + ); + + expect(vm.$el.querySelector('.js-sources-dropdown li a').getAttribute('href')).toEqual( + release.assets.sources[0].url, + ); + + expect(vm.$el.querySelector('.js-sources-dropdown li a').textContent).toContain( + release.assets.sources[0].format, + ); + }); + + it('renders list with the links provided', () => { + expect(vm.$el.querySelectorAll('.js-assets-list li').length).toEqual( + release.assets.links.length, + ); + + expect(vm.$el.querySelector('.js-assets-list li a').getAttribute('href')).toEqual( + release.assets.links[0].url, + ); + + expect(vm.$el.querySelector('.js-assets-list li a').textContent).toContain( + release.assets.links[0].name, + ); + }); +}); diff --git a/spec/javascripts/releases/mock_data.js b/spec/javascripts/releases/mock_data.js new file mode 100644 index 00000000000..2855eca1711 --- /dev/null +++ b/spec/javascripts/releases/mock_data.js @@ -0,0 +1,128 @@ +export const release = { + name: 'Bionic Beaver', + tag_name: '18.04', + description: '## changelog\n\n* line 1\n* line2', + description_html: '<div><h2>changelog</h2><ul><li>line1</li<li>line 2</li></ul></div>', + author_name: 'Release bot', + author_email: 'release-bot@example.com', + created_at: '2012-05-28T05:00:00-07:00', + commit: { + id: '2695effb5807a22ff3d138d593fd856244e155e7', + short_id: '2695effb', + title: 'Initial commit', + created_at: '2017-07-26T11:08:53.000+02:00', + parent_ids: ['2a4b78934375d7f53875269ffd4f45fd83a84ebe'], + message: 'Initial commit', + author: { + avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png', + id: 482476, + name: 'John Doe', + path: '/johndoe', + state: 'active', + status_tooltip_html: null, + username: 'johndoe', + web_url: 'https://gitlab.com/johndoe', + }, + authored_date: '2012-05-28T04:42:42-07:00', + committer_name: 'Jack Smith', + committer_email: 'jack@example.com', + committed_date: '2012-05-28T04:42:42-07:00', + }, + assets: { + count: 6, + sources: [ + { + format: 'zip', + url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.zip', + }, + { + format: 'tar.gz', + url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.gz', + }, + { + format: 'tar.bz2', + url: + 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.bz2', + }, + { + format: 'tar', + url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar', + }, + ], + links: [ + { + name: 'release-18.04.dmg', + url: 'https://my-external-hosting.example.com/scrambled-url/', + external: true, + }, + { + name: 'binary-linux-amd64', + url: + 'https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50', + external: false, + }, + ], + }, +}; + +export const releases = [ + release, + { + name: 'JoJos Bizarre Adventure', + tag_name: '19.00', + description: '## changelog\n\n* line 1\n* line2', + description_html: '<div><h2>changelog</h2><ul><li>line1</li<li>line 2</li></ul></div>', + author_name: 'Release bot', + author_email: 'release-bot@example.com', + created_at: '2012-05-28T05:00:00-07:00', + commit: { + id: '2695effb5807a22ff3d138d593fd856244e155e7', + short_id: '2695effb', + title: 'Initial commit', + created_at: '2017-07-26T11:08:53.000+02:00', + parent_ids: ['2a4b78934375d7f53875269ffd4f45fd83a84ebe'], + message: 'Initial commit', + author: { + avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png', + id: 482476, + name: 'John Doe', + path: '/johndoe', + state: 'active', + status_tooltip_html: null, + username: 'johndoe', + web_url: 'https://gitlab.com/johndoe', + }, + authored_date: '2012-05-28T04:42:42-07:00', + committer_name: 'Jack Smith', + committer_email: 'jack@example.com', + committed_date: '2012-05-28T04:42:42-07:00', + }, + assets: { + count: 4, + sources: [ + { + format: 'tar.gz', + url: + 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.gz', + }, + { + format: 'tar.bz2', + url: + 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.bz2', + }, + { + format: 'tar', + url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar', + }, + ], + links: [ + { + name: 'binary-linux-amd64', + url: + 'https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50', + external: false, + }, + ], + }, + }, +]; diff --git a/spec/javascripts/releases/store/actions_spec.js b/spec/javascripts/releases/store/actions_spec.js new file mode 100644 index 00000000000..6eb8e681be9 --- /dev/null +++ b/spec/javascripts/releases/store/actions_spec.js @@ -0,0 +1,98 @@ +import { + requestReleases, + fetchReleases, + receiveReleasesSuccess, + receiveReleasesError, +} from '~/releases/store/actions'; +import state from '~/releases/store/state'; +import * as types from '~/releases/store/mutation_types'; +import api from '~/api'; +import testAction from 'spec/helpers/vuex_action_helper'; +import { releases } from '../mock_data'; + +describe('Releases State actions', () => { + let mockedState; + + beforeEach(() => { + mockedState = state(); + }); + + describe('requestReleases', () => { + it('should commit REQUEST_RELEASES mutation', done => { + testAction(requestReleases, null, mockedState, [{ type: types.REQUEST_RELEASES }], [], done); + }); + }); + + describe('fetchReleases', () => { + describe('success', () => { + it('dispatches requestReleases and receiveReleasesSuccess ', done => { + spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: releases })); + + testAction( + fetchReleases, + releases, + mockedState, + [], + [ + { + type: 'requestReleases', + }, + { + payload: releases, + type: 'receiveReleasesSuccess', + }, + ], + done, + ); + }); + }); + + describe('error', () => { + it('dispatches requestReleases and receiveReleasesError ', done => { + spyOn(api, 'releases').and.returnValue(Promise.reject()); + + testAction( + fetchReleases, + null, + mockedState, + [], + [ + { + type: 'requestReleases', + }, + { + type: 'receiveReleasesError', + }, + ], + done, + ); + }); + }); + }); + + describe('receiveReleasesSuccess', () => { + it('should commit RECEIVE_RELEASES_SUCCESS mutation', done => { + testAction( + receiveReleasesSuccess, + releases, + mockedState, + [{ type: types.RECEIVE_RELEASES_SUCCESS, payload: releases }], + [], + done, + ); + }); + }); + + describe('receiveReleasesError', () => { + it('should commit RECEIVE_RELEASES_ERROR mutation', done => { + testAction( + receiveReleasesError, + null, + mockedState, + [{ type: types.RECEIVE_RELEASES_ERROR }], + [], + done, + ); + }); + }); +}); diff --git a/spec/javascripts/releases/store/helpers.js b/spec/javascripts/releases/store/helpers.js new file mode 100644 index 00000000000..e962b254377 --- /dev/null +++ b/spec/javascripts/releases/store/helpers.js @@ -0,0 +1,6 @@ +import state from '~/releases/store/state'; + +// eslint-disable-next-line import/prefer-default-export +export const resetStore = store => { + store.replaceState(state()); +}; diff --git a/spec/javascripts/releases/store/mutations_spec.js b/spec/javascripts/releases/store/mutations_spec.js new file mode 100644 index 00000000000..72b98529fe9 --- /dev/null +++ b/spec/javascripts/releases/store/mutations_spec.js @@ -0,0 +1,47 @@ +import state from '~/releases/store/state'; +import mutations from '~/releases/store/mutations'; +import * as types from '~/releases/store/mutation_types'; +import { releases } from '../mock_data'; + +describe('Releases Store Mutations', () => { + let stateCopy; + + beforeEach(() => { + stateCopy = state(); + }); + + describe('REQUEST_RELEASES', () => { + it('sets isLoading to true', () => { + mutations[types.REQUEST_RELEASES](stateCopy); + + expect(stateCopy.isLoading).toEqual(true); + }); + }); + + describe('RECEIVE_RELEASES_SUCCESS', () => { + beforeEach(() => { + mutations[types.RECEIVE_RELEASES_SUCCESS](stateCopy, releases); + }); + + it('sets is loading to false', () => { + expect(stateCopy.isLoading).toEqual(false); + }); + + it('sets hasError to false', () => { + expect(stateCopy.hasError).toEqual(false); + }); + + it('sets data', () => { + expect(stateCopy.releases).toEqual(releases); + }); + }); + + describe('RECEIVE_RELEASES_ERROR', () => { + it('resets data', () => { + mutations[types.RECEIVE_RELEASES_ERROR](stateCopy); + + expect(stateCopy.isLoading).toEqual(false); + expect(stateCopy.releases).toEqual([]); + }); + }); +}); diff --git a/spec/javascripts/sidebar/mock_data.js b/spec/javascripts/sidebar/mock_data.js index fcd7bea3f6d..7f20b0da991 100644 --- a/spec/javascripts/sidebar/mock_data.js +++ b/spec/javascripts/sidebar/mock_data.js @@ -66,7 +66,7 @@ const RESPONSE_MAP = { }, labels: [], }, - '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar': { + '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras': { assignees: [ { name: 'User 0', @@ -181,7 +181,7 @@ const RESPONSE_MAP = { const mockData = { responseMap: RESPONSE_MAP, mediator: { - endpoint: '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar', + endpoint: '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras', toggleSubscriptionEndpoint: '/gitlab-org/gitlab-shell/issues/5/toggle_subscription', moveIssueEndpoint: '/gitlab-org/gitlab-shell/issues/5/move', projectsAutocompleteEndpoint: '/autocomplete/projects?project_id=15', diff --git a/spec/javascripts/sidebar/sidebar_mediator_spec.js b/spec/javascripts/sidebar/sidebar_mediator_spec.js index 2d853970fc4..6c69c08e733 100644 --- a/spec/javascripts/sidebar/sidebar_mediator_spec.js +++ b/spec/javascripts/sidebar/sidebar_mediator_spec.js @@ -37,7 +37,7 @@ describe('Sidebar mediator', function() { it('fetches the data', done => { const mockData = - Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar']; + Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras']; spyOn(this.mediator, 'processFetchedData').and.callThrough(); this.mediator @@ -51,7 +51,7 @@ describe('Sidebar mediator', function() { it('processes fetched data', () => { const mockData = - Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar']; + Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras']; this.mediator.processFetchedData(mockData); expect(this.mediator.store.assignees).toEqual(mockData.assignees); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js index 300133dc602..212519743aa 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js @@ -114,7 +114,7 @@ describe('Merge request widget rebase component', () => { // Wait for the eventHub to be called .then(vm.$nextTick()) .then(() => { - expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested'); + expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetRebaseSuccess'); }) .then(done) .catch(done.fail); diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js index f72bf627c10..99b80df766a 100644 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js @@ -18,6 +18,8 @@ describe('mrWidgetOptions', () => { let vm; let MrWidgetOptions; + const COLLABORATION_MESSAGE = 'Allows commits from members who can merge to the target branch'; + beforeEach(() => { // Prevent component mounting delete mrWidgetOptions.el; @@ -132,6 +134,53 @@ describe('mrWidgetOptions', () => { expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); }); }); + + describe('shouldRenderCollaborationStatus', () => { + describe('when collaboration is allowed', () => { + beforeEach(() => { + vm.mr.allowCollaboration = true; + }); + + describe('when merge request is opened', () => { + beforeEach(done => { + vm.mr.isOpen = true; + vm.$nextTick(done); + }); + + it('should render collaboration status', () => { + expect(vm.$el.textContent).toContain(COLLABORATION_MESSAGE); + }); + }); + + describe('when merge request is not opened', () => { + beforeEach(done => { + vm.mr.isOpen = false; + vm.$nextTick(done); + }); + + it('should not render collaboration status', () => { + expect(vm.$el.textContent).not.toContain(COLLABORATION_MESSAGE); + }); + }); + }); + + describe('when collaboration is not allowed', () => { + beforeEach(() => { + vm.mr.allowCollaboration = false; + }); + + describe('when merge request is opened', () => { + beforeEach(done => { + vm.mr.isOpen = true; + vm.$nextTick(done); + }); + + it('should not render collaboration status', () => { + expect(vm.$el.textContent).not.toContain(COLLABORATION_MESSAGE); + }); + }); + }); + }); }); describe('methods', () => { diff --git a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js index 9d34bdd1084..61ef26cd080 100644 --- a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js +++ b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js @@ -35,7 +35,7 @@ describe('getStateKey', () => { expect(bound()).toEqual('mergeWhenPipelineSucceeds'); - context.hasSHAChanged = true; + context.isSHAMismatch = true; expect(bound()).toEqual('shaMismatch'); diff --git a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js index f5079147f60..c226704694c 100644 --- a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js +++ b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js @@ -3,23 +3,30 @@ import { stateKey } from '~/vue_merge_request_widget/stores/state_maps'; import mockData from '../mock_data'; describe('MergeRequestStore', () => { - describe('setData', () => { - let store; + let store; - beforeEach(() => { - store = new MergeRequestStore(mockData); - }); + beforeEach(() => { + store = new MergeRequestStore(mockData); + }); - it('should set hasSHAChanged when the diff SHA changes', () => { + describe('setData', () => { + it('should set isSHAMismatch when the diff SHA changes', () => { store.setData({ ...mockData, diff_head_sha: 'a-different-string' }); - expect(store.hasSHAChanged).toBe(true); + expect(store.isSHAMismatch).toBe(true); }); - it('should not set hasSHAChanged when other data changes', () => { + it('should not set isSHAMismatch when other data changes', () => { store.setData({ ...mockData, work_in_progress: !mockData.work_in_progress }); - expect(store.hasSHAChanged).toBe(false); + expect(store.isSHAMismatch).toBe(false); + }); + + it('should update cached sha after rebasing', () => { + store.setData({ ...mockData, diff_head_sha: 'abc123' }, true); + + expect(store.isSHAMismatch).toBe(false); + expect(store.sha).toBe('abc123'); }); describe('isPipelinePassing', () => { diff --git a/spec/javascripts/vue_shared/components/markdown/field_spec.js b/spec/javascripts/vue_shared/components/markdown/field_spec.js index abb17440c0e..79e0e756a7a 100644 --- a/spec/javascripts/vue_shared/components/markdown/field_spec.js +++ b/spec/javascripts/vue_shared/components/markdown/field_spec.js @@ -80,7 +80,7 @@ describe('Markdown field component', () => { previewLink.click(); Vue.nextTick(() => { - expect(vm.$el.querySelector('.md-preview').textContent.trim()).toContain('Loading...'); + expect(vm.$el.querySelector('.md-preview').textContent.trim()).toContain('Loading…'); done(); }); diff --git a/spec/javascripts/vue_shared/components/markdown/header_spec.js b/spec/javascripts/vue_shared/components/markdown/header_spec.js index 59613faa49f..e733a95288e 100644 --- a/spec/javascripts/vue_shared/components/markdown/header_spec.js +++ b/spec/javascripts/vue_shared/components/markdown/header_spec.js @@ -28,6 +28,7 @@ describe('Markdown field header component', () => { 'Add a numbered list', 'Add a task list', 'Add a table', + 'Insert suggestion', 'Go full screen', ]; const elements = vm.$el.querySelectorAll('.toolbar-btn'); @@ -93,4 +94,18 @@ describe('Markdown field header component', () => { '| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |', ); }); + + it('renders suggestion template', () => { + vm.lineContent = 'Some content'; + + expect(vm.mdSuggestion).toEqual('```suggestion\n{text}\n```'); + }); + + it('does not render suggestion button if `canSuggest` is set to false', () => { + vm.canSuggest = false; + + Vue.nextTick(() => { + expect(vm.$el.querySelector('.qa-suggestion-btn')).toBe(null); + }); + }); }); diff --git a/spec/javascripts/vue_shared/components/markdown/suggestion_diff_header_spec.js b/spec/javascripts/vue_shared/components/markdown/suggestion_diff_header_spec.js new file mode 100644 index 00000000000..8187b3204b1 --- /dev/null +++ b/spec/javascripts/vue_shared/components/markdown/suggestion_diff_header_spec.js @@ -0,0 +1,69 @@ +import Vue from 'vue'; +import SuggestionDiffHeaderComponent from '~/vue_shared/components/markdown/suggestion_diff_header.vue'; + +const MOCK_DATA = { + canApply: true, + isApplied: false, + helpPagePath: 'path_to_docs', +}; + +describe('Suggestion Diff component', () => { + let vm; + + function createComponent(propsData) { + const Component = Vue.extend(SuggestionDiffHeaderComponent); + + return new Component({ + propsData, + }).$mount(); + } + + beforeEach(done => { + vm = createComponent(MOCK_DATA); + Vue.nextTick(done); + }); + + describe('init', () => { + it('renders a suggestion header', () => { + const header = vm.$el.querySelector('.qa-suggestion-diff-header'); + + expect(header).not.toBeNull(); + expect(header.innerHTML.includes('Suggested change')).toBe(true); + }); + + it('renders an apply button', () => { + const applyBtn = vm.$el.querySelector('.qa-apply-btn'); + + expect(applyBtn).not.toBeNull(); + expect(applyBtn.innerHTML.includes('Apply suggestion')).toBe(true); + }); + + it('does not render an apply button if `canApply` is set to false', () => { + const props = Object.assign(MOCK_DATA, { canApply: false }); + + vm = createComponent(props); + + expect(vm.$el.querySelector('.qa-apply-btn')).toBeNull(); + }); + }); + + describe('applySuggestion', () => { + it('emits when the apply button is clicked', () => { + const props = Object.assign(MOCK_DATA, { canApply: true }); + + vm = createComponent(props); + spyOn(vm, '$emit'); + vm.applySuggestion(); + + expect(vm.$emit).toHaveBeenCalled(); + }); + + it('does not emit when the canApply is set to false', () => { + spyOn(vm, '$emit'); + vm.canApply = false; + vm.applySuggestion(); + + expect(vm.$emit).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/javascripts/vue_shared/components/markdown/suggestion_diff_spec.js b/spec/javascripts/vue_shared/components/markdown/suggestion_diff_spec.js new file mode 100644 index 00000000000..d4ed8f2f7a4 --- /dev/null +++ b/spec/javascripts/vue_shared/components/markdown/suggestion_diff_spec.js @@ -0,0 +1,79 @@ +import Vue from 'vue'; +import SuggestionDiffComponent from '~/vue_shared/components/markdown/suggestion_diff.vue'; + +const MOCK_DATA = { + canApply: true, + newLines: [ + { content: 'Line 1\n', lineNumber: 1 }, + { content: 'Line 2\n', lineNumber: 2 }, + { content: 'Line 3\n', lineNumber: 3 }, + ], + fromLine: 1, + fromContent: 'Old content', + suggestion: { + id: 1, + }, + helpPagePath: 'path_to_docs', +}; + +describe('Suggestion Diff component', () => { + let vm; + + beforeEach(done => { + const Component = Vue.extend(SuggestionDiffComponent); + + vm = new Component({ + propsData: MOCK_DATA, + }).$mount(); + + Vue.nextTick(done); + }); + + describe('init', () => { + it('renders a suggestion header', () => { + expect(vm.$el.querySelector('.qa-suggestion-diff-header')).not.toBeNull(); + }); + + it('renders a diff table', () => { + expect(vm.$el.querySelector('table.md-suggestion-diff')).not.toBeNull(); + }); + + it('renders the oldLineNumber', () => { + const fromLine = vm.$el.querySelector('.qa-old-diff-line-number').innerHTML; + + expect(parseInt(fromLine, 10)).toBe(vm.fromLine); + }); + + it('renders the oldLineContent', () => { + const fromContent = vm.$el.querySelector('.line_content.old').innerHTML; + + expect(fromContent.includes(vm.fromContent)).toBe(true); + }); + + it('renders the contents of newLines', () => { + const newLines = vm.$el.querySelectorAll('.line_holder.new'); + + newLines.forEach((line, i) => { + expect(newLines[i].innerHTML.includes(vm.newLines[i].content)).toBe(true); + }); + }); + + it('renders a line number for each line', () => { + const newLineNumbers = vm.$el.querySelectorAll('.qa-new-diff-line-number'); + + newLineNumbers.forEach((line, i) => { + expect(newLineNumbers[i].innerHTML.includes(vm.newLines[i].lineNumber)).toBe(true); + }); + }); + }); + + describe('applySuggestion', () => { + it('emits apply event when applySuggestion is called', () => { + const callback = () => {}; + spyOn(vm, '$emit'); + vm.applySuggestion(callback); + + expect(vm.$emit).toHaveBeenCalledWith('apply', { suggestionId: vm.suggestion.id, callback }); + }); + }); +}); diff --git a/spec/javascripts/vue_shared/components/markdown/suggestions_spec.js b/spec/javascripts/vue_shared/components/markdown/suggestions_spec.js new file mode 100644 index 00000000000..ab1b747c360 --- /dev/null +++ b/spec/javascripts/vue_shared/components/markdown/suggestions_spec.js @@ -0,0 +1,125 @@ +import Vue from 'vue'; +import SuggestionsComponent from '~/vue_shared/components/markdown/suggestions.vue'; + +const MOCK_DATA = { + fromLine: 1, + fromContent: 'Old content', + suggestions: [], + noteHtml: ` + <div class="suggestion"> + <div class="line">Suggestion 1</div> + </div> + + <div class="suggestion"> + <div class="line">Suggestion 2</div> + </div> + `, + isApplied: false, + helpPagePath: 'path_to_docs', +}; + +const generateLine = content => { + const line = document.createElement('div'); + line.className = 'line'; + line.innerHTML = content; + + return line; +}; + +const generateMockLines = () => { + const line1 = generateLine('Line 1'); + const line2 = generateLine('Line 2'); + const line3 = generateLine('Line 3'); + const container = document.createElement('div'); + + container.appendChild(line1); + container.appendChild(line2); + container.appendChild(line3); + + return container; +}; + +describe('Suggestion component', () => { + let vm; + let extractedLines; + let diffTable; + + beforeEach(done => { + const Component = Vue.extend(SuggestionsComponent); + + vm = new Component({ + propsData: MOCK_DATA, + }).$mount(); + + extractedLines = vm.extractNewLines(generateMockLines()); + diffTable = vm.generateDiff(extractedLines).$mount().$el; + + spyOn(vm, 'renderSuggestions'); + vm.renderSuggestions(); + Vue.nextTick(done); + }); + + describe('mounted', () => { + it('renders a flash container', () => { + expect(vm.$el.querySelector('.flash-container')).not.toBeNull(); + }); + + it('renders a container for suggestions', () => { + expect(vm.$refs.container).not.toBeNull(); + }); + + it('renders suggestions', () => { + expect(vm.renderSuggestions).toHaveBeenCalled(); + expect(vm.$el.innerHTML.includes('Suggestion 1')).toBe(true); + expect(vm.$el.innerHTML.includes('Suggestion 2')).toBe(true); + }); + }); + + describe('extractNewLines', () => { + it('extracts suggested lines', () => { + const expectedReturn = [ + { content: 'Line 1\n', lineNumber: 1 }, + { content: 'Line 2\n', lineNumber: 2 }, + { content: 'Line 3\n', lineNumber: 3 }, + ]; + + expect(vm.extractNewLines(generateMockLines())).toEqual(expectedReturn); + }); + + it('increments line number for each extracted line', () => { + expect(extractedLines[0].lineNumber).toEqual(1); + expect(extractedLines[1].lineNumber).toEqual(2); + expect(extractedLines[2].lineNumber).toEqual(3); + }); + + it('returns empty array if no lines are found', () => { + const el = document.createElement('div'); + + expect(vm.extractNewLines(el)).toEqual([]); + }); + }); + + describe('generateDiff', () => { + it('generates a diff table', () => { + expect(diffTable.querySelector('.md-suggestion-diff')).not.toBeNull(); + }); + + it('generates a diff table that contains contents of `oldLineContent`', () => { + expect(diffTable.innerHTML.includes(vm.fromContent)).toBe(true); + }); + + it('generates a diff table that contains contents the suggested lines', () => { + extractedLines.forEach((line, i) => { + expect(diffTable.innerHTML.includes(extractedLines[i].content)).toBe(true); + }); + }); + + it('generates a diff table with the correct line number for each suggested line', () => { + const lines = diffTable.getElementsByClassName('qa-new-diff-line-number'); + + expect([...lines][0].innerHTML).toBe('1'); + expect([...lines][1].innerHTML).toBe('2'); + expect([...lines][2].innerHTML).toBe('3'); + }); + }); +}); diff --git a/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js b/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js index 1578b0f81f9..25b6e3b6bc8 100644 --- a/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js +++ b/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js @@ -89,7 +89,7 @@ describe('User Popover Component', () => { expect(vm.$el.textContent).toContain('GitLab'); }); - it('should have full job line when we have bio and organization', () => { + it('should display bio and organization in separate lines', () => { const testProps = Object.assign({}, DEFAULT_PROPS); testProps.user.bio = 'Engineer'; testProps.user.organization = 'GitLab'; @@ -99,7 +99,24 @@ describe('User Popover Component', () => { target: document.querySelector('.js-user-link'), }); - expect(vm.$el.textContent).toContain('Engineer at GitLab'); + expect(vm.$el.querySelector('.js-bio').textContent).toContain('Engineer'); + expect(vm.$el.querySelector('.js-organization').textContent).toContain('GitLab'); + }); + + it('should not encode special characters in bio and organization', () => { + const testProps = Object.assign({}, DEFAULT_PROPS); + testProps.user.bio = 'Manager & Team Lead'; + testProps.user.organization = 'Me & my <funky> Company'; + + vm = mountComponent(UserPopover, { + ...DEFAULT_PROPS, + target: document.querySelector('.js-user-link'), + }); + + expect(vm.$el.querySelector('.js-bio').textContent).toContain('Manager & Team Lead'); + expect(vm.$el.querySelector('.js-organization').textContent).toContain( + 'Me & my <funky> Company', + ); }); }); diff --git a/spec/lib/api/helpers_spec.rb b/spec/lib/api/helpers_spec.rb index 58a49124ce6..1c73a936e17 100644 --- a/spec/lib/api/helpers_spec.rb +++ b/spec/lib/api/helpers_spec.rb @@ -148,4 +148,36 @@ describe API::Helpers do it_behaves_like 'user namespace finder' end + + describe '#send_git_blob' do + context 'content disposition' do + let(:repository) { double } + let(:blob) { double(name: 'foobar') } + + let(:send_git_blob) do + subject.send(:send_git_blob, repository, blob) + end + + before do + allow(subject).to receive(:env).and_return({}) + allow(subject).to receive(:content_type) + allow(subject).to receive(:header).and_return({}) + allow(Gitlab::Workhorse).to receive(:send_git_blob) + end + + context 'when blob name is null' do + let(:blob) { double(name: nil) } + + it 'returns only the disposition' do + expect(send_git_blob['Content-Disposition']).to eq 'attachment' + end + end + + context 'when blob name is not null' do + it 'returns disposition with the blob name' do + expect(send_git_blob['Content-Disposition']).to eq 'attachment; filename="foobar"' + end + end + end + end end diff --git a/spec/lib/backup/repository_spec.rb b/spec/lib/backup/repository_spec.rb index fdeea814bb2..5ace5c5b1a2 100644 --- a/spec/lib/backup/repository_spec.rb +++ b/spec/lib/backup/repository_spec.rb @@ -67,6 +67,19 @@ describe Backup::Repository do end end end + + context 'restoring object pools' do + it 'schedules restoring of the pool' do + pool_repository = create(:pool_repository, :failed) + pool_repository.delete_object_pool + + subject.restore + + pool_repository.reload + expect(pool_repository).not_to be_failed + expect(pool_repository.object_pool.exists?).to be(true) + end + end end describe '#prepare_directories', :seed_helper do diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb index 1a87cfa5b45..4c94e4fdae0 100644 --- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb @@ -59,7 +59,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do it 'links with adjacent text' do doc = reference_filter("Milestone (#{reference}.)") - expect(doc.to_html).to match(%r(\(<a.+>#{milestone.name}</a>\.\))) + expect(doc.to_html).to match(%r(\(<a.+>#{milestone.reference_link_text}</a>\.\))) end it 'ignores invalid milestone IIDs' do @@ -80,12 +80,12 @@ describe Banzai::Filter::MilestoneReferenceFilter do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls.milestone_url(milestone) - expect(doc.text).to eq 'See gfm' + expect(doc.text).to eq "See #{milestone.reference_link_text}" end it 'links with adjacent text' do doc = reference_filter("Milestone (#{reference}.)") - expect(doc.to_html).to match(%r(\(<a.+>#{milestone.name}</a>\.\))) + expect(doc.to_html).to match(%r(\(<a.+>#{milestone.reference_link_text}</a>\.\))) end it 'ignores invalid milestone names' do @@ -106,12 +106,12 @@ describe Banzai::Filter::MilestoneReferenceFilter do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls.milestone_url(milestone) - expect(doc.text).to eq 'See gfm references' + expect(doc.text).to eq "See #{milestone.reference_link_text}" end it 'links with adjacent text' do doc = reference_filter("Milestone (#{reference}.)") - expect(doc.to_html).to match(%r(\(<a.+>#{milestone.name}</a>\.\))) + expect(doc.to_html).to match(%r(\(<a.+>#{milestone.reference_link_text}</a>\.\))) end it 'ignores invalid milestone names' do @@ -201,14 +201,14 @@ describe Banzai::Filter::MilestoneReferenceFilter do doc = reference_filter("See (#{reference}.)") expect(doc.css('a').first.text) - .to eq("#{milestone.name} in #{another_project.full_path}") + .to eq("#{milestone.reference_link_text} in #{another_project.full_path}") end it 'has valid text' do doc = reference_filter("See (#{reference}.)") expect(doc.text) - .to eq("See (#{milestone.name} in #{another_project.full_path}.)") + .to eq("See (#{milestone.reference_link_text} in #{another_project.full_path}.)") end it 'escapes the name attribute' do @@ -217,7 +217,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do doc = reference_filter("See #{reference}") expect(doc.css('a').first.text) - .to eq "#{milestone.name} in #{another_project.full_path}" + .to eq "#{milestone.reference_link_text} in #{another_project.full_path}" end end @@ -238,14 +238,14 @@ describe Banzai::Filter::MilestoneReferenceFilter do doc = reference_filter("See (#{reference}.)") expect(doc.css('a').first.text) - .to eq("#{milestone.name} in #{another_project.path}") + .to eq("#{milestone.reference_link_text} in #{another_project.path}") end it 'has valid text' do doc = reference_filter("See (#{reference}.)") expect(doc.text) - .to eq("See (#{milestone.name} in #{another_project.path}.)") + .to eq("See (#{milestone.reference_link_text} in #{another_project.path}.)") end it 'escapes the name attribute' do @@ -254,7 +254,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do doc = reference_filter("See #{reference}") expect(doc.css('a').first.text) - .to eq "#{milestone.name} in #{another_project.path}" + .to eq "#{milestone.reference_link_text} in #{another_project.path}" end end @@ -275,14 +275,14 @@ describe Banzai::Filter::MilestoneReferenceFilter do doc = reference_filter("See (#{reference}.)") expect(doc.css('a').first.text) - .to eq("#{milestone.name} in #{another_project.path}") + .to eq("#{milestone.reference_link_text} in #{another_project.path}") end it 'has valid text' do doc = reference_filter("See (#{reference}.)") expect(doc.text) - .to eq("See (#{milestone.name} in #{another_project.path}.)") + .to eq("See (#{milestone.reference_link_text} in #{another_project.path}.)") end it 'escapes the name attribute' do @@ -291,7 +291,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do doc = reference_filter("See #{reference}") expect(doc.css('a').first.text) - .to eq "#{milestone.name} in #{another_project.path}" + .to eq "#{milestone.reference_link_text} in #{another_project.path}" end end @@ -346,7 +346,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do milestone.update!(group: parent_group) doc = reference_filter("See #{reference}") - expect(doc.css('a').first.text).to eq(milestone.name) + expect(doc.css('a').first.text).to eq(milestone.reference_link_text) end end diff --git a/spec/lib/banzai/filter/suggestion_filter_spec.rb b/spec/lib/banzai/filter/suggestion_filter_spec.rb new file mode 100644 index 00000000000..b13c90b54bd --- /dev/null +++ b/spec/lib/banzai/filter/suggestion_filter_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Banzai::Filter::SuggestionFilter do + include FilterSpecHelper + + let(:input) { "<pre class='code highlight js-syntax-highlight suggestion'><code>foo\n</code></pre>" } + let(:default_context) do + { suggestions_filter_enabled: true } + end + + it 'includes `js-render-suggestion` class' do + doc = filter(input, default_context) + result = doc.css('code').first + + expect(result[:class]).to include('js-render-suggestion') + end + + it 'includes no `js-render-suggestion` when filter is disabled' do + doc = filter(input) + result = doc.css('code').first + + expect(result[:class]).to be_nil + end +end diff --git a/spec/lib/banzai/suggestions_parser_spec.rb b/spec/lib/banzai/suggestions_parser_spec.rb new file mode 100644 index 00000000000..79658d710ce --- /dev/null +++ b/spec/lib/banzai/suggestions_parser_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Banzai::SuggestionsParser do + describe '.parse' do + it 'returns a list of suggestion contents' do + markdown = <<-MARKDOWN.strip_heredoc + ```suggestion + foo + bar + ``` + + ``` + nothing + ``` + + ```suggestion + xpto + baz + ``` + + ```thing + this is not a suggestion, it's a thing + ``` + MARKDOWN + + expect(described_class.parse(markdown)).to eq([" foo\n bar", + " xpto\n baz"]) + end + end +end diff --git a/spec/lib/constraints/feature_constrainer_spec.rb b/spec/lib/constraints/feature_constrainer_spec.rb new file mode 100644 index 00000000000..42efc164f81 --- /dev/null +++ b/spec/lib/constraints/feature_constrainer_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe Constraints::FeatureConstrainer do + describe '#matches' do + it 'calls Feature.enabled? with the correct arguments' do + expect(Feature).to receive(:enabled?).with(:feature_name, "an object", default_enabled: true) + + described_class.new(:feature_name, "an object", default_enabled: true).matches?(double('request')) + end + end +end diff --git a/spec/lib/gitlab/background_migration/backfill_hashed_project_repositories_spec.rb b/spec/lib/gitlab/background_migration/backfill_hashed_project_repositories_spec.rb index b6c1edbbf8b..e802613490b 100644 --- a/spec/lib/gitlab/background_migration/backfill_hashed_project_repositories_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_hashed_project_repositories_spec.rb @@ -3,88 +3,5 @@ require 'spec_helper' describe Gitlab::BackgroundMigration::BackfillHashedProjectRepositories, :migration, schema: 20181130102132 do - let(:namespaces) { table(:namespaces) } - let(:project_repositories) { table(:project_repositories) } - let(:projects) { table(:projects) } - let(:shards) { table(:shards) } - let(:group) { namespaces.create!(name: 'foo', path: 'foo') } - let(:shard) { shards.create!(name: 'default') } - - describe described_class::ShardFinder do - describe '#find_shard_id' do - it 'creates a new shard when it does not exist yet' do - expect { subject.find_shard_id('other') }.to change(shards, :count).by(1) - end - - it 'returns the shard when it exists' do - shards.create(id: 5, name: 'other') - - shard_id = subject.find_shard_id('other') - - expect(shard_id).to eq(5) - end - - it 'only queries the database once to retrieve shards' do - subject.find_shard_id('default') - - expect { subject.find_shard_id('default') }.not_to exceed_query_limit(0) - end - end - end - - describe described_class::Project do - describe '.on_hashed_storage' do - it 'finds projects with repository on hashed storage' do - projects.create!(id: 1, name: 'foo', path: 'foo', namespace_id: group.id, storage_version: 1) - projects.create!(id: 2, name: 'bar', path: 'bar', namespace_id: group.id, storage_version: 2) - projects.create!(id: 3, name: 'baz', path: 'baz', namespace_id: group.id, storage_version: 0) - projects.create!(id: 4, name: 'zoo', path: 'zoo', namespace_id: group.id, storage_version: nil) - - expect(described_class.on_hashed_storage.pluck(:id)).to match_array([1, 2]) - end - end - - describe '.without_project_repository' do - it 'finds projects which do not have a projects_repositories entry' do - projects.create!(id: 1, name: 'foo', path: 'foo', namespace_id: group.id) - projects.create!(id: 2, name: 'bar', path: 'bar', namespace_id: group.id) - project_repositories.create!(project_id: 2, disk_path: '@phony/foo/bar', shard_id: shard.id) - - expect(described_class.without_project_repository.pluck(:id)).to contain_exactly(1) - end - end - end - - describe '#perform' do - it 'creates a project_repository row for projects on hashed storage that need one' do - projects.create!(id: 1, name: 'foo', path: 'foo', namespace_id: group.id, storage_version: 1) - projects.create!(id: 2, name: 'bar', path: 'bar', namespace_id: group.id, storage_version: 2) - - expect { described_class.new.perform(1, projects.last.id) }.to change(project_repositories, :count).by(2) - end - - it 'does nothing for projects on hashed storage that have already a project_repository row' do - projects.create!(id: 1, name: 'foo', path: 'foo', namespace_id: group.id, storage_version: 1) - project_repositories.create!(project_id: 1, disk_path: '@phony/foo/bar', shard_id: shard.id) - - expect { described_class.new.perform(1, projects.last.id) }.not_to change(project_repositories, :count) - end - - it 'does nothing for projects on legacy storage' do - projects.create!(name: 'foo', path: 'foo', namespace_id: group.id, storage_version: 0) - - expect { described_class.new.perform(1, projects.last.id) }.not_to change(project_repositories, :count) - end - - it 'inserts rows in a single query' do - projects.create!(name: 'foo', path: 'foo', namespace_id: group.id, storage_version: 1, repository_storage: shard.name) - - control_count = ActiveRecord::QueryRecorder.new { described_class.new.perform(1, projects.last.id) } - - projects.create!(name: 'bar', path: 'bar', namespace_id: group.id, storage_version: 1, repository_storage: shard.name) - projects.create!(name: 'zoo', path: 'zoo', namespace_id: group.id, storage_version: 1, repository_storage: shard.name) - - expect { described_class.new.perform(1, projects.last.id) }.not_to exceed_query_limit(control_count) - end - end + it_behaves_like 'backfill migration for project repositories', :hashed end diff --git a/spec/lib/gitlab/background_migration/backfill_legacy_project_repositories_spec.rb b/spec/lib/gitlab/background_migration/backfill_legacy_project_repositories_spec.rb new file mode 100644 index 00000000000..ae4b53d62e6 --- /dev/null +++ b/spec/lib/gitlab/background_migration/backfill_legacy_project_repositories_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::BackgroundMigration::BackfillLegacyProjectRepositories, :migration, schema: 20181218192239 do + it_behaves_like 'backfill migration for project repositories', :legacy +end diff --git a/spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb new file mode 100644 index 00000000000..53c071f0268 --- /dev/null +++ b/spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::BackgroundMigration::BackfillProjectRepositories do + let(:group) { create(:group, name: 'foo', path: 'foo') } + + describe described_class::ShardFinder do + let(:shard) { create(:shard, name: 'default') } + + describe '#find_shard_id' do + it 'creates a new shard when it does not exist yet' do + expect { subject.find_shard_id('other') }.to change(Shard, :count).by(1) + end + + it 'returns the shard when it exists' do + other_shard = create(:shard, name: 'other') + + shard_id = subject.find_shard_id('other') + + expect(shard_id).to eq(other_shard.id) + end + + it 'only queries the database once to retrieve shards' do + subject.find_shard_id('default') + + expect { subject.find_shard_id('default') }.not_to exceed_query_limit(0) + end + end + end + + describe described_class::Project do + let!(:project_hashed_storage_1) { create(:project, name: 'foo', path: 'foo', namespace: group, storage_version: 1) } + let!(:project_hashed_storage_2) { create(:project, name: 'bar', path: 'bar', namespace: group, storage_version: 2) } + let!(:project_legacy_storage_3) { create(:project, name: 'baz', path: 'baz', namespace: group, storage_version: 0) } + let!(:project_legacy_storage_4) { create(:project, name: 'zoo', path: 'zoo', namespace: group, storage_version: nil) } + + describe '.on_hashed_storage' do + it 'finds projects with repository on hashed storage' do + projects = described_class.on_hashed_storage.pluck(:id) + + expect(projects).to match_array([project_hashed_storage_1.id, project_hashed_storage_2.id]) + end + end + + describe '.on_legacy_storage' do + it 'finds projects with repository on legacy storage' do + projects = described_class.on_legacy_storage.pluck(:id) + + expect(projects).to match_array([project_legacy_storage_3.id, project_legacy_storage_4.id]) + end + end + + describe '.without_project_repository' do + it 'finds projects which do not have a projects_repositories entry' do + create(:project_repository, project: project_hashed_storage_1) + create(:project_repository, project: project_legacy_storage_3) + + projects = described_class.without_project_repository.pluck(:id) + + expect(projects).to contain_exactly(project_hashed_storage_2.id, project_legacy_storage_4.id) + end + end + + describe '#disk_path' do + context 'for projects on hashed storage' do + it 'returns the correct disk_path' do + project = described_class.find(project_hashed_storage_1.id) + + expect(project.disk_path).to eq(project_hashed_storage_1.disk_path) + end + end + + context 'for projects on legacy storage' do + it 'returns the correct disk_path' do + project = described_class.find(project_legacy_storage_3.id) + + expect(project.disk_path).to eq(project_legacy_storage_3.disk_path) + end + + it 'raises OrphanedNamespaceError when any parent namespace does not exist' do + subgroup = create(:group, parent: group) + project_orphaned_namespace = create(:project, name: 'baz', path: 'baz', namespace: subgroup, storage_version: nil) + subgroup.update_column(:parent_id, Namespace.maximum(:id).succ) + + project = described_class.find(project_orphaned_namespace.id) + + expect { project.disk_path } + .to raise_error(Gitlab::BackgroundMigration::BackfillProjectRepositories::OrphanedNamespaceError) + end + end + end + end +end diff --git a/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb b/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb index 5ce84c61042..7c7e58d6bb7 100644 --- a/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb +++ b/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb @@ -6,8 +6,18 @@ describe Gitlab::BackgroundMigration::MigrateBuildStage, :migration, schema: 201 let(:stages) { table(:ci_stages) } let(:jobs) { table(:ci_builds) } - STATUSES = { created: 0, pending: 1, running: 2, success: 3, - failed: 4, canceled: 5, skipped: 6, manual: 7 }.freeze + let(:statuses) do + { + created: 0, + pending: 1, + running: 2, + success: 3, + failed: 4, + canceled: 5, + skipped: 6, + manual: 7 + } + end before do projects.create!(id: 123, name: 'gitlab', path: 'gitlab-ce') @@ -36,9 +46,9 @@ describe Gitlab::BackgroundMigration::MigrateBuildStage, :migration, schema: 201 expect(stages.all.pluck(:name)).to match_array %w[test build deploy] expect(jobs.where(stage_id: nil)).to be_one expect(jobs.find_by(stage_id: nil).id).to eq 6 - expect(stages.all.pluck(:status)).to match_array [STATUSES[:success], - STATUSES[:failed], - STATUSES[:pending]] + expect(stages.all.pluck(:status)).to match_array [statuses[:success], + statuses[:failed], + statuses[:pending]] end it 'recovers from unique constraint violation only twice' do diff --git a/spec/lib/gitlab/background_migration/migrate_stage_status_spec.rb b/spec/lib/gitlab/background_migration/migrate_stage_status_spec.rb index 878158910be..89b56906ed0 100644 --- a/spec/lib/gitlab/background_migration/migrate_stage_status_spec.rb +++ b/spec/lib/gitlab/background_migration/migrate_stage_status_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::MigrateStageStatus, :migration, schema: 20170711145320 do @@ -6,8 +8,18 @@ describe Gitlab::BackgroundMigration::MigrateStageStatus, :migration, schema: 20 let(:stages) { table(:ci_stages) } let(:jobs) { table(:ci_builds) } - STATUSES = { created: 0, pending: 1, running: 2, success: 3, - failed: 4, canceled: 5, skipped: 6, manual: 7 }.freeze + let(:statuses) do + { + created: 0, + pending: 1, + running: 2, + success: 3, + failed: 4, + canceled: 5, + skipped: 6, + manual: 7 + } + end before do projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1') @@ -26,8 +38,8 @@ describe Gitlab::BackgroundMigration::MigrateStageStatus, :migration, schema: 20 it 'sets a correct stage status' do described_class.new.perform(1, 2) - expect(stages.first.status).to eq STATUSES[:running] - expect(stages.second.status).to eq STATUSES[:failed] + expect(stages.first.status).to eq statuses[:running] + expect(stages.second.status).to eq statuses[:failed] end end @@ -35,8 +47,8 @@ describe Gitlab::BackgroundMigration::MigrateStageStatus, :migration, schema: 20 it 'sets a skipped stage status' do described_class.new.perform(1, 2) - expect(stages.first.status).to eq STATUSES[:skipped] - expect(stages.second.status).to eq STATUSES[:skipped] + expect(stages.first.status).to eq statuses[:skipped] + expect(stages.second.status).to eq statuses[:skipped] end end @@ -50,8 +62,8 @@ describe Gitlab::BackgroundMigration::MigrateStageStatus, :migration, schema: 20 it 'sets a correct stage status' do described_class.new.perform(1, 2) - expect(stages.first.status).to eq STATUSES[:canceled] - expect(stages.second.status).to eq STATUSES[:success] + expect(stages.first.status).to eq statuses[:canceled] + expect(stages.second.status).to eq statuses[:success] end end @@ -65,8 +77,8 @@ describe Gitlab::BackgroundMigration::MigrateStageStatus, :migration, schema: 20 it 'sets a correct stage status' do described_class.new.perform(1, 2) - expect(stages.first.status).to eq STATUSES[:manual] - expect(stages.second.status).to eq STATUSES[:success] + expect(stages.first.status).to eq statuses[:manual] + expect(stages.second.status).to eq statuses[:success] end end diff --git a/spec/lib/gitlab/bare_repository_import/importer_spec.rb b/spec/lib/gitlab/bare_repository_import/importer_spec.rb index 3c63e601abc..f4759b69538 100644 --- a/spec/lib/gitlab/bare_repository_import/importer_spec.rb +++ b/spec/lib/gitlab/bare_repository_import/importer_spec.rb @@ -192,7 +192,7 @@ describe Gitlab::BareRepositoryImport::Importer, :seed_helper do let(:project_path) { 'a-group/a-sub-group/a-project' } before do - expect(Group).to receive(:supports_nested_groups?) { false } + expect(Group).to receive(:supports_nested_objects?) { false } end describe '#create_project_if_needed' do diff --git a/spec/lib/gitlab/blob_helper_spec.rb b/spec/lib/gitlab/blob_helper_spec.rb index 0b56f8687c3..e057385b35f 100644 --- a/spec/lib/gitlab/blob_helper_spec.rb +++ b/spec/lib/gitlab/blob_helper_spec.rb @@ -53,11 +53,11 @@ describe Gitlab::BlobHelper do describe '#text?' do it 'returns true' do - expect(blob.text?).to be_truthy + expect(blob.text_in_repo?).to be_truthy end it 'returns false' do - expect(large_blob.text?).to be_falsey + expect(large_blob.text_in_repo?).to be_falsey end end diff --git a/spec/lib/gitlab/checks/diff_check_spec.rb b/spec/lib/gitlab/checks/diff_check_spec.rb index eeec1e83179..a341dfa5636 100644 --- a/spec/lib/gitlab/checks/diff_check_spec.rb +++ b/spec/lib/gitlab/checks/diff_check_spec.rb @@ -47,5 +47,43 @@ describe Gitlab::Checks::DiffCheck do end end end + + context 'commit diff validations' do + before do + allow(subject).to receive(:validations_for_diff).and_return([lambda { |diff| return }]) + + expect_any_instance_of(Commit).to receive(:raw_deltas).and_call_original + + subject.validate! + end + + context 'when request store is inactive' do + it 'are run for every commit' do + expect_any_instance_of(Commit).to receive(:raw_deltas).and_call_original + + subject.validate! + end + end + + context 'when request store is active', :request_store do + it 'are cached for every commit' do + expect_any_instance_of(Commit).not_to receive(:raw_deltas) + + subject.validate! + end + + it 'are run for not cached commits' do + allow(project.repository).to receive(:new_commits).and_return( + project.repository.commits_between('be93687618e4b132087f430a4d8fc3a609c9b77c', 'a5391128b0ef5d21df5dd23d98557f4ef12fae20') + ) + change_access.instance_variable_set(:@commits, project.repository.new_commits) + + expect(project.repository.new_commits.first).not_to receive(:raw_deltas).and_call_original + expect(project.repository.new_commits.last).to receive(:raw_deltas).and_call_original + + subject.validate! + end + end + end end end diff --git a/spec/lib/gitlab/ci/config/entry/except_policy_spec.rb b/spec/lib/gitlab/ci/config/entry/except_policy_spec.rb deleted file mode 100644 index d036bf2f4d1..00000000000 --- a/spec/lib/gitlab/ci/config/entry/except_policy_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Gitlab::Ci::Config::Entry::ExceptPolicy do - let(:entry) { described_class.new(config) } - - it_behaves_like 'correct only except policy' - - describe '.default' do - it 'does not have a default value' do - expect(described_class.default).to be_nil - end - end -end diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index 12f4b9dc624..61d78f86b51 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -161,7 +161,8 @@ describe Gitlab::Ci::Config::Entry::Global do variables: { 'VAR' => 'value' }, ignore: false, after_script: ['make clean'], - only: { refs: %w[branches tags] } }, + only: { refs: %w[branches tags] }, + except: {} }, spinach: { name: :spinach, before_script: [], script: %w[spinach], @@ -173,7 +174,8 @@ describe Gitlab::Ci::Config::Entry::Global do variables: {}, ignore: false, after_script: ['make clean'], - only: { refs: %w[branches tags] } } + only: { refs: %w[branches tags] }, + except: {} } ) end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index c1f4a060063..8e32cede3b5 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -259,7 +259,8 @@ describe Gitlab::Ci::Config::Entry::Job do stage: 'test', ignore: false, after_script: %w[cleanup], - only: { refs: %w[branches tags] }) + only: { refs: %w[branches tags] }, + except: {}) end end end diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb index 2a753408f54..1a2c30d3571 100644 --- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb @@ -68,13 +68,15 @@ describe Gitlab::Ci::Config::Entry::Jobs do commands: 'rspec', ignore: false, stage: 'test', - only: { refs: %w[branches tags] } }, + only: { refs: %w[branches tags] }, + except: {} }, spinach: { name: :spinach, script: %w[spinach], commands: 'spinach', ignore: false, stage: 'test', - only: { refs: %w[branches tags] } }) + only: { refs: %w[branches tags] }, + except: {} }) end end diff --git a/spec/lib/gitlab/ci/config/entry/only_policy_spec.rb b/spec/lib/gitlab/ci/config/entry/only_policy_spec.rb deleted file mode 100644 index 5518b68e51a..00000000000 --- a/spec/lib/gitlab/ci/config/entry/only_policy_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Gitlab::Ci::Config::Entry::OnlyPolicy do - let(:entry) { described_class.new(config) } - - it_behaves_like 'correct only except policy' - - describe '.default' do - it 'haa a default value' do - expect(described_class.default).to eq( { refs: %w[branches tags] } ) - end - end -end diff --git a/spec/lib/gitlab/ci/config/entry/policy_spec.rb b/spec/lib/gitlab/ci/config/entry/policy_spec.rb index cf40a22af2e..83001b7fdd8 100644 --- a/spec/lib/gitlab/ci/config/entry/policy_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/policy_spec.rb @@ -1,8 +1,173 @@ -require 'spec_helper' +require 'fast_spec_helper' +require_dependency 'active_model' describe Gitlab::Ci::Config::Entry::Policy do let(:entry) { described_class.new(config) } + context 'when using simplified policy' do + describe 'validations' do + context 'when entry config value is valid' do + context 'when config is a branch or tag name' do + let(:config) { %w[master feature/branch] } + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + + describe '#value' do + it 'returns refs hash' do + expect(entry.value).to eq(refs: config) + end + end + end + + context 'when config is a regexp' do + let(:config) { ['/^issue-.*$/'] } + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when config is a special keyword' do + let(:config) { %w[tags triggers branches] } + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + end + + context 'when entry value is not valid' do + let(:config) { [1] } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include /policy config should be an array of strings or regexps/ + end + end + end + end + end + + context 'when using complex policy' do + context 'when specifying refs policy' do + let(:config) { { refs: ['master'] } } + + it 'is a correct configuraton' do + expect(entry).to be_valid + expect(entry.value).to eq(refs: %w[master]) + end + end + + context 'when specifying kubernetes policy' do + let(:config) { { kubernetes: 'active' } } + + it 'is a correct configuraton' do + expect(entry).to be_valid + expect(entry.value).to eq(kubernetes: 'active') + end + end + + context 'when specifying invalid kubernetes policy' do + let(:config) { { kubernetes: 'something' } } + + it 'reports an error about invalid policy' do + expect(entry.errors).to include /unknown value: something/ + end + end + + context 'when specifying valid variables expressions policy' do + let(:config) { { variables: ['$VAR == null'] } } + + it 'is a correct configuraton' do + expect(entry).to be_valid + expect(entry.value).to eq(config) + end + end + + context 'when specifying variables expressions in invalid format' do + let(:config) { { variables: '$MY_VAR' } } + + it 'reports an error about invalid format' do + expect(entry.errors).to include /should be an array of strings/ + end + end + + context 'when specifying invalid variables expressions statement' do + let(:config) { { variables: ['$MY_VAR =='] } } + + it 'reports an error about invalid statement' do + expect(entry.errors).to include /invalid expression syntax/ + end + end + + context 'when specifying invalid variables expressions token' do + let(:config) { { variables: ['$MY_VAR == 123'] } } + + it 'reports an error about invalid expression' do + expect(entry.errors).to include /invalid expression syntax/ + end + end + + context 'when using invalid variables expressions regexp' do + let(:config) { { variables: ['$MY_VAR =~ /some ( thing/'] } } + + it 'reports an error about invalid expression' do + expect(entry.errors).to include /invalid expression syntax/ + end + end + + context 'when specifying a valid changes policy' do + let(:config) { { changes: %w[some/* paths/**/*.rb] } } + + it 'is a correct configuraton' do + expect(entry).to be_valid + expect(entry.value).to eq(config) + end + end + + context 'when changes policy is invalid' do + let(:config) { { changes: [1, 2] } } + + it 'returns errors' do + expect(entry.errors).to include /changes should be an array of strings/ + end + end + + context 'when specifying unknown policy' do + let(:config) { { refs: ['master'], invalid: :something } } + + it 'returns error about invalid key' do + expect(entry.errors).to include /unknown keys: invalid/ + end + end + + context 'when policy is empty' do + let(:config) { {} } + + it 'is not a valid configuration' do + expect(entry.errors).to include /can't be blank/ + end + end + end + + context 'when policy strategy does not match' do + let(:config) { 'string strategy' } + + it 'returns information about errors' do + expect(entry.errors) + .to include /has to be either an array of conditions or a hash/ + end + end + describe '.default' do it 'does not have a default value' do expect(described_class.default).to be_nil diff --git a/spec/lib/gitlab/ci/config/external/file/local_spec.rb b/spec/lib/gitlab/ci/config/external/file/local_spec.rb index 541deb13b97..645db642e29 100644 --- a/spec/lib/gitlab/ci/config/external/file/local_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/local_spec.rb @@ -44,7 +44,6 @@ describe Gitlab::Ci::Config::External::File::Local do - apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs - ruby -v - which ruby - - gem install bundler --no-ri --no-rdoc - bundle install --jobs $(nproc) "${FLAGS[@]}" HEREDOC end diff --git a/spec/lib/gitlab/ci/config/external/file/remote_spec.rb b/spec/lib/gitlab/ci/config/external/file/remote_spec.rb index 7c1a1c38736..eaf621e4140 100644 --- a/spec/lib/gitlab/ci/config/external/file/remote_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/remote_spec.rb @@ -11,7 +11,6 @@ describe Gitlab::Ci::Config::External::File::Remote do - apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs - ruby -v - which ruby - - gem install bundler --no-ri --no-rdoc - bundle install --jobs $(nproc) "${FLAGS[@]}" HEREDOC end diff --git a/spec/lib/gitlab/ci/config/external/processor_spec.rb b/spec/lib/gitlab/ci/config/external/processor_spec.rb index 1a05f716247..dbd28e9745c 100644 --- a/spec/lib/gitlab/ci/config/external/processor_spec.rb +++ b/spec/lib/gitlab/ci/config/external/processor_spec.rb @@ -51,7 +51,6 @@ describe Gitlab::Ci::Config::External::Processor do - apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs - ruby -v - which ruby - - gem install bundler --no-ri --no-rdoc - bundle install --jobs $(nproc) "${FLAGS[@]}" rspec: @@ -86,7 +85,6 @@ describe Gitlab::Ci::Config::External::Processor do - apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs - ruby -v - which ruby - - gem install bundler --no-ri --no-rdoc - bundle install --jobs $(nproc) "${FLAGS[@]}" HEREDOC end diff --git a/spec/lib/gitlab/ci/config_spec.rb b/spec/lib/gitlab/ci/config_spec.rb index 975e11e8cc1..ea6f1e20014 100644 --- a/spec/lib/gitlab/ci/config_spec.rb +++ b/spec/lib/gitlab/ci/config_spec.rb @@ -170,7 +170,6 @@ describe Gitlab::Ci::Config do before_script_values = [ "apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs", "ruby -v", "which ruby", - "gem install bundler --no-ri --no-rdoc", "bundle install --jobs $(nproc) \"${FLAGS[@]}\"" ] variables = { diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb index 55490f37ac7..caf9fc5442c 100644 --- a/spec/lib/gitlab/current_settings_spec.rb +++ b/spec/lib/gitlab/current_settings_spec.rb @@ -54,7 +54,7 @@ describe Gitlab::CurrentSettings do expect(ApplicationSetting).not_to receive(:current) end - it 'returns an in-memory ApplicationSetting object' do + it 'returns a FakeApplicationSettings object' do expect(described_class.current_application_settings).to be_a(Gitlab::FakeApplicationSettings) end @@ -91,6 +91,14 @@ describe Gitlab::CurrentSettings do allow(ActiveRecord::Base.connection).to receive(:cached_table_exists?).with('application_settings').and_return(true) end + context 'with RequestStore enabled', :request_store do + it 'fetches the settings from DB only once' do + described_class.current_application_settings # warm the cache + + expect(ActiveRecord::QueryRecorder.new { described_class.current_application_settings }.count).to eq(0) + end + end + it 'creates default ApplicationSettings if none are present' do settings = described_class.current_application_settings @@ -99,34 +107,45 @@ describe Gitlab::CurrentSettings do expect(settings).to have_attributes(settings_from_defaults) end - context 'with migrations pending' do + context 'with pending migrations' do before do expect(ActiveRecord::Migrator).to receive(:needs_migration?).and_return(true) end - it 'returns an in-memory ApplicationSetting object' do - settings = described_class.current_application_settings + shared_examples 'a non-persisted ApplicationSetting object' do + let(:current_settings) { described_class.current_application_settings } + + it 'returns a non-persisted ApplicationSetting object' do + expect(current_settings).to be_a(ApplicationSetting) + expect(current_settings).not_to be_persisted + end + + it 'uses the default value from ApplicationSetting.defaults' do + expect(current_settings.signup_enabled).to eq(ApplicationSetting.defaults[:signup_enabled]) + end + + it 'uses the default value from custom ApplicationSetting accessors' do + expect(current_settings.commit_email_hostname).to eq(ApplicationSetting.default_commit_email_hostname) + end + + it 'responds to predicate methods' do + expect(current_settings.signup_enabled?).to eq(current_settings.signup_enabled) + end + end - expect(settings).to be_a(Gitlab::FakeApplicationSettings) - expect(settings.sign_in_enabled?).to eq(settings.sign_in_enabled) - expect(settings.sign_up_enabled?).to eq(settings.sign_up_enabled) + context 'with no ApplicationSetting DB record' do + it_behaves_like 'a non-persisted ApplicationSetting object' end - it 'uses the existing database settings and falls back to defaults' do - db_settings = create(:application_setting, - home_page_url: 'http://mydomain.com', - signup_enabled: false) - settings = described_class.current_application_settings - app_defaults = ApplicationSetting.last - - expect(settings).to be_a(Gitlab::FakeApplicationSettings) - expect(settings.home_page_url).to eq(db_settings.home_page_url) - expect(settings.signup_enabled?).to be_falsey - expect(settings.signup_enabled).to be_falsey - - # Check that unspecified values use the defaults - settings.reject! { |key, _| [:home_page_url, :signup_enabled].include? key } - settings.each { |key, _| expect(settings[key]).to eq(app_defaults[key]) } + context 'with an existing ApplicationSetting DB record' do + let!(:db_settings) { ApplicationSetting.build_from_defaults(home_page_url: 'http://mydomain.com').save! && ApplicationSetting.last } + let(:current_settings) { described_class.current_application_settings } + + it_behaves_like 'a non-persisted ApplicationSetting object' + + it 'uses the value from the DB attribute if present and not overriden by an accessor' do + expect(current_settings.home_page_url).to eq(db_settings.home_page_url) + end end end @@ -138,17 +157,12 @@ describe Gitlab::CurrentSettings do end end - context 'when the application_settings table does not exists' do - it 'returns an in-memory ApplicationSetting object' do - expect(ApplicationSetting).to receive(:create_from_defaults).and_raise(ActiveRecord::StatementInvalid) - - expect(described_class.current_application_settings).to be_a(Gitlab::FakeApplicationSettings) - end - end - - context 'when the application_settings table is not fully migrated' do - it 'returns an in-memory ApplicationSetting object' do - expect(ApplicationSetting).to receive(:create_from_defaults).and_raise(ActiveRecord::UnknownAttributeError) + context 'when the application_settings table does not exist' do + it 'returns a FakeApplicationSettings object' do + expect(Gitlab::Database) + .to receive(:cached_table_exists?) + .with('application_settings') + .and_return(false) expect(described_class.current_application_settings).to be_a(Gitlab::FakeApplicationSettings) end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 23f27939dd2..4e83b27e4a5 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -1338,12 +1338,7 @@ describe Gitlab::Database::MigrationHelpers do end describe '#index_exists_by_name?' do - # TODO: remove rails5-only after removing rails4 tests - # rails 4 can not handle multiple indexes on the same column set if - # index was added by 't.index' - t.index is used by default in schema.rb in - # rails 5. Let's run this test only in rails 5 env: - # see https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/21492#note_113602758 - it 'returns true if an index exists', :rails5 do + it 'returns true if an index exists' do expect(model.index_exists_by_name?(:projects, 'index_projects_on_path')) .to be_truthy end diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index fc295b2deff..60106ee3c0b 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -400,13 +400,8 @@ describe Gitlab::Database do describe '.cached_table_exists?' do it 'only retrieves data once per table' do - if Gitlab.rails5? - expect(ActiveRecord::Base.connection).to receive(:data_source_exists?).with(:projects).once.and_call_original - expect(ActiveRecord::Base.connection).to receive(:data_source_exists?).with(:bogus_table_name).once.and_call_original - else - expect(ActiveRecord::Base.connection).to receive(:table_exists?).with(:projects).once.and_call_original - expect(ActiveRecord::Base.connection).to receive(:table_exists?).with(:bogus_table_name).once.and_call_original - end + expect(ActiveRecord::Base.connection).to receive(:data_source_exists?).with(:projects).once.and_call_original + expect(ActiveRecord::Base.connection).to receive(:data_source_exists?).with(:bogus_table_name).once.and_call_original 2.times do expect(described_class.cached_table_exists?(:projects)).to be_truthy @@ -462,8 +457,7 @@ describe Gitlab::Database do expect(described_class.db_read_only?).to be_truthy end - # TODO: remove rails5-only tag after removing rails4 tests - it 'detects a read only database', :rails5 do + it 'detects a read only database' do allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => true }]) expect(described_class.db_read_only?).to be_truthy @@ -475,8 +469,7 @@ describe Gitlab::Database do expect(described_class.db_read_only?).to be_falsey end - # TODO: remove rails5-only tag after removing rails4 tests - it 'detects a read write database', :rails5 do + it 'detects a read write database' do allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => false }]) expect(described_class.db_read_only?).to be_falsey diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb index 3417896e259..862590268ca 100644 --- a/spec/lib/gitlab/diff/file_spec.rb +++ b/spec/lib/gitlab/diff/file_spec.rb @@ -310,7 +310,7 @@ describe Gitlab::Diff::File do context 'when the content changed' do context 'when the file represented by the diff file is binary' do before do - allow(diff_file).to receive(:raw_binary?).and_return(true) + allow(diff_file).to receive(:binary?).and_return(true) end it 'returns a No Preview viewer' do @@ -345,7 +345,7 @@ describe Gitlab::Diff::File do context 'when the file represented by the diff file is binary' do before do - allow(diff_file).to receive(:raw_binary?).and_return(true) + allow(diff_file).to receive(:binary?).and_return(true) end it 'returns an Added viewer' do @@ -380,7 +380,7 @@ describe Gitlab::Diff::File do context 'when the file represented by the diff file is binary' do before do - allow(diff_file).to receive(:raw_binary?).and_return(true) + allow(diff_file).to receive(:binary?).and_return(true) end it 'returns a Deleted viewer' do @@ -436,7 +436,7 @@ describe Gitlab::Diff::File do allow(diff_file).to receive(:deleted_file?).and_return(false) allow(diff_file).to receive(:renamed_file?).and_return(false) allow(diff_file).to receive(:mode_changed?).and_return(false) - allow(diff_file).to receive(:raw_text?).and_return(false) + allow(diff_file).to receive(:text?).and_return(false) end it 'returns a No Preview viewer' do @@ -583,6 +583,12 @@ describe Gitlab::Diff::File do end end + describe '#empty?' do + it 'returns true' do + expect(diff_file.empty?).to be_truthy + end + end + describe '#different_type?' do it 'returns false' do expect(diff_file).not_to be_different_type @@ -662,4 +668,87 @@ describe Gitlab::Diff::File do end end end + + describe '#empty?' do + let(:project) do + create(:project, :custom_repo, files: {}) + end + let(:branch_name) { 'master' } + + def create_file(file_name, content) + Files::CreateService.new( + project, + project.owner, + commit_message: 'Update', + start_branch: branch_name, + branch_name: branch_name, + file_path: file_name, + file_content: content + ).execute + + project.commit(branch_name).diffs.diff_files.first + end + + def update_file(file_name, content) + Files::UpdateService.new( + project, + project.owner, + commit_message: 'Update', + start_branch: branch_name, + branch_name: branch_name, + file_path: file_name, + file_content: content + ).execute + + project.commit(branch_name).diffs.diff_files.first + end + + def delete_file(file_name) + Files::DeleteService.new( + project, + project.owner, + commit_message: 'Update', + start_branch: branch_name, + branch_name: branch_name, + file_path: file_name + ).execute + + project.commit(branch_name).diffs.diff_files.first + end + + context 'when empty file is created' do + it 'returns true' do + diff_file = create_file('empty.md', '') + + expect(diff_file.empty?).to be_truthy + end + end + + context 'when empty file is deleted' do + it 'returns true' do + create_file('empty.md', '') + diff_file = delete_file('empty.md') + + expect(diff_file.empty?).to be_truthy + end + end + + context 'when file with content is truncated' do + it 'returns false' do + create_file('with-content.md', 'file content') + diff_file = update_file('with-content.md', '') + + expect(diff_file.empty?).to be_falsey + end + end + + context 'when empty file has content added' do + it 'returns false' do + create_file('empty.md', '') + diff_file = update_file('empty.md', 'new content') + + expect(diff_file.empty?).to be_falsey + end + end + end end diff --git a/spec/lib/gitlab/diff/lines_unfolder_spec.rb b/spec/lib/gitlab/diff/lines_unfolder_spec.rb index 8e00c8e0e30..f22c2c90334 100644 --- a/spec/lib/gitlab/diff/lines_unfolder_spec.rb +++ b/spec/lib/gitlab/diff/lines_unfolder_spec.rb @@ -185,7 +185,7 @@ describe Gitlab::Diff::LinesUnfolder do let(:project) { create(:project) } - let(:old_blob) { Gitlab::Git::Blob.new(data: raw_old_blob) } + let(:old_blob) { Blob.decorate(Gitlab::Git::Blob.new(data: raw_old_blob, size: 10)) } let(:diff) do Gitlab::Git::Diff.new(diff: raw_diff, diff --git a/spec/lib/gitlab/discussions_diff/file_collection_spec.rb b/spec/lib/gitlab/discussions_diff/file_collection_spec.rb new file mode 100644 index 00000000000..0489206458b --- /dev/null +++ b/spec/lib/gitlab/discussions_diff/file_collection_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::DiscussionsDiff::FileCollection do + let(:merge_request) { create(:merge_request) } + let!(:diff_note_a) { create(:diff_note_on_merge_request, project: merge_request.project, noteable: merge_request) } + let!(:diff_note_b) { create(:diff_note_on_merge_request, project: merge_request.project, noteable: merge_request) } + let(:note_diff_file_a) { diff_note_a.note_diff_file } + let(:note_diff_file_b) { diff_note_b.note_diff_file } + + subject { described_class.new([note_diff_file_a, note_diff_file_b]) } + + describe '#load_highlight', :clean_gitlab_redis_shared_state do + it 'writes uncached diffs highlight' do + file_a_caching_content = diff_note_a.diff_file.highlighted_diff_lines.map(&:to_hash) + file_b_caching_content = diff_note_b.diff_file.highlighted_diff_lines.map(&:to_hash) + + expect(Gitlab::DiscussionsDiff::HighlightCache) + .to receive(:write_multiple) + .with({ note_diff_file_a.id => file_a_caching_content, + note_diff_file_b.id => file_b_caching_content }) + .and_call_original + + subject.load_highlight([note_diff_file_a.id, note_diff_file_b.id]) + end + + it 'does not write cache for already cached file' do + subject.load_highlight([note_diff_file_a.id]) + + file_b_caching_content = diff_note_b.diff_file.highlighted_diff_lines.map(&:to_hash) + + expect(Gitlab::DiscussionsDiff::HighlightCache) + .to receive(:write_multiple) + .with({ note_diff_file_b.id => file_b_caching_content }) + .and_call_original + + subject.load_highlight([note_diff_file_a.id, note_diff_file_b.id]) + end + + it 'does not err when given ID does not exist in @collection' do + expect { subject.load_highlight([999]) }.not_to raise_error + end + + it 'loaded diff files have highlighted lines loaded' do + subject.load_highlight([note_diff_file_a.id]) + + diff_file = subject.find_by_id(note_diff_file_a.id) + + expect(diff_file.highlight_loaded?).to be(true) + end + + it 'not loaded diff files does not have highlighted lines loaded' do + subject.load_highlight([note_diff_file_a.id]) + + diff_file = subject.find_by_id(note_diff_file_b.id) + + expect(diff_file.highlight_loaded?).to be(false) + end + end +end diff --git a/spec/lib/gitlab/discussions_diff/highlight_cache_spec.rb b/spec/lib/gitlab/discussions_diff/highlight_cache_spec.rb new file mode 100644 index 00000000000..fe26ebb8796 --- /dev/null +++ b/spec/lib/gitlab/discussions_diff/highlight_cache_spec.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::DiscussionsDiff::HighlightCache, :clean_gitlab_redis_cache do + describe '#write_multiple' do + it 'sets multiple keys serializing content as JSON' do + mapping = { + 3 => [ + { + text: 'foo', + type: 'new', + index: 2, + old_pos: 10, + new_pos: 11, + line_code: 'xpto', + rich_text: '<blips>blops</blips>' + }, + { + text: 'foo', + type: 'new', + index: 3, + old_pos: 11, + new_pos: 12, + line_code: 'xpto', + rich_text: '<blops>blips</blops>' + } + ] + } + + described_class.write_multiple(mapping) + + mapping.each do |key, value| + full_key = described_class.cache_key_for(key) + found = Gitlab::Redis::Cache.with { |r| r.get(full_key) } + + expect(found).to eq(value.to_json) + end + end + end + + describe '#read_multiple' do + it 'reads multiple keys and serializes content into Gitlab::Diff::Line objects' do + mapping = { + 3 => [ + { + text: 'foo', + type: 'new', + index: 2, + old_pos: 11, + new_pos: 12, + line_code: 'xpto', + rich_text: '<blips>blops</blips>' + }, + { + text: 'foo', + type: 'new', + index: 3, + old_pos: 10, + new_pos: 11, + line_code: 'xpto', + rich_text: '<blips>blops</blips>' + } + ] + } + + described_class.write_multiple(mapping) + + found = described_class.read_multiple(mapping.keys) + + expect(found.size).to eq(1) + expect(found.first.size).to eq(2) + expect(found.first).to all(be_a(Gitlab::Diff::Line)) + end + + it 'returns nil when cached key is not found' do + mapping = { + 3 => [ + { + text: 'foo', + type: 'new', + index: 2, + old_pos: 11, + new_pos: 12, + line_code: 'xpto', + rich_text: '<blips>blops</blips>' + } + ] + } + + described_class.write_multiple(mapping) + + found = described_class.read_multiple([2, 3]) + + expect(found.size).to eq(2) + + expect(found.first).to eq(nil) + expect(found.second.size).to eq(1) + expect(found.second).to all(be_a(Gitlab::Diff::Line)) + end + end +end diff --git a/spec/lib/gitlab/encoding_helper_spec.rb b/spec/lib/gitlab/encoding_helper_spec.rb index a5bf2f2b3df..429816efec3 100644 --- a/spec/lib/gitlab/encoding_helper_spec.rb +++ b/spec/lib/gitlab/encoding_helper_spec.rb @@ -124,7 +124,7 @@ describe Gitlab::EncodingHelper do end it 'returns empty string on conversion errors' do - expect { ext_class.encode_utf8('') }.not_to raise_error(ArgumentError) + expect { ext_class.encode_utf8('') }.not_to raise_error end context 'with strings that can be forcefully encoded into utf8' do diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb index 80dd3dcc58e..1bcec04d28f 100644 --- a/spec/lib/gitlab/git/blob_spec.rb +++ b/spec/lib/gitlab/git/blob_spec.rb @@ -59,7 +59,7 @@ describe Gitlab::Git::Blob, :seed_helper do it { expect(blob.data[0..10]).to eq("*.rbc\n*.sas") } it { expect(blob.size).to eq(241) } it { expect(blob.mode).to eq("100644") } - it { expect(blob).not_to be_binary } + it { expect(blob).not_to be_binary_in_repo } end context 'file in root with leading slash' do @@ -92,7 +92,7 @@ describe Gitlab::Git::Blob, :seed_helper do end it 'does not mark the blob as binary' do - expect(blob).not_to be_binary + expect(blob).not_to be_binary_in_repo end end @@ -123,7 +123,7 @@ describe Gitlab::Git::Blob, :seed_helper do .with(hash_including(binary: true)) .and_call_original - expect(blob).to be_binary + expect(blob).to be_binary_in_repo end end end @@ -196,7 +196,7 @@ describe Gitlab::Git::Blob, :seed_helper do it { expect(blob.id).to eq('409f37c4f05865e4fb208c771485f211a22c4c2d') } it { expect(blob.data).to eq('') } it 'does not mark the blob as binary' do - expect(blob).not_to be_binary + expect(blob).not_to be_binary_in_repo end end diff --git a/spec/lib/gitlab/git/object_pool_spec.rb b/spec/lib/gitlab/git/object_pool_spec.rb index 363c2aa67af..0d5069568e1 100644 --- a/spec/lib/gitlab/git/object_pool_spec.rb +++ b/spec/lib/gitlab/git/object_pool_spec.rb @@ -56,16 +56,11 @@ describe Gitlab::Git::ObjectPool do describe '#link' do let!(:pool_repository) { create(:pool_repository, :ready) } - context 'when no remotes are set' do + context 'when linked for the first time' do it 'sets a remote' do - subject.link(source_repository) - - repo = Gitlab::GitalyClient::StorageSettings.allow_disk_access do - Rugged::Repository.new(subject.repository.path) - end - - expect(repo.remotes.count).to be(1) - expect(repo.remotes.first.name).to eq(source_repository.object_pool_remote_name) + expect do + subject.link(source_repository) + end.not_to raise_error end end @@ -75,14 +70,9 @@ describe Gitlab::Git::ObjectPool do end it "doesn't raise an error" do - subject.link(source_repository) - - repo = Gitlab::GitalyClient::StorageSettings.allow_disk_access do - Rugged::Repository.new(subject.repository.path) - end - - expect(repo.remotes.count).to be(1) - expect(repo.remotes.first.name).to eq(source_repository.object_pool_remote_name) + expect do + subject.link(source_repository) + end.not_to raise_error end end end diff --git a/spec/lib/gitlab/git/repository_cleaner_spec.rb b/spec/lib/gitlab/git/repository_cleaner_spec.rb index a9d9e67ef94..7f9cc2bc9ec 100644 --- a/spec/lib/gitlab/git/repository_cleaner_spec.rb +++ b/spec/lib/gitlab/git/repository_cleaner_spec.rb @@ -1,31 +1,61 @@ require 'spec_helper' describe Gitlab::Git::RepositoryCleaner do + include HttpIOHelpers + let(:project) { create(:project, :repository) } let(:repository) { project.repository } let(:head_sha) { repository.head_commit.id } - - let(:object_map) { StringIO.new("#{head_sha} #{'0' * 40}") } + let(:object_map_data) { "#{head_sha} #{'0' * 40}" } subject(:cleaner) { described_class.new(repository.raw) } describe '#apply_bfg_object_map' do - it 'removes internal references pointing at SHAs in the object map' do - # Create some refs we expect to be removed - repository.keep_around(head_sha) - repository.create_ref(head_sha, 'refs/environments/1') - repository.create_ref(head_sha, 'refs/merge-requests/1') - repository.create_ref(head_sha, 'refs/heads/_keep') - repository.create_ref(head_sha, 'refs/tags/_keep') - - cleaner.apply_bfg_object_map(object_map) - - aggregate_failures do - expect(repository.kept_around?(head_sha)).to be_falsy - expect(repository.ref_exists?('refs/environments/1')).to be_falsy - expect(repository.ref_exists?('refs/merge-requests/1')).to be_falsy - expect(repository.ref_exists?('refs/heads/_keep')).to be_truthy - expect(repository.ref_exists?('refs/tags/_keep')).to be_truthy + let(:clean_refs) { %W[refs/environments/1 refs/merge-requests/1 refs/keep-around/#{head_sha}] } + let(:keep_refs) { %w[refs/heads/_keep refs/tags/_keep] } + + before do + (clean_refs + keep_refs).each { |ref| repository.create_ref(head_sha, ref) } + end + + context 'from StringIO' do + let(:object_map) { StringIO.new(object_map_data) } + + it 'removes internal references' do + cleaner.apply_bfg_object_map(object_map) + + aggregate_failures do + clean_refs.each { |ref| expect(repository.ref_exists?(ref)).to be_falsy } + keep_refs.each { |ref| expect(repository.ref_exists?(ref)).to be_truthy } + end + end + end + + context 'from Gitlab::HttpIO' do + let(:url) { 'http://example.com/bfg_object_map.txt' } + let(:tempfile) { Tempfile.new } + let(:object_map) { Gitlab::HttpIO.new(url, object_map_data.size) } + + around do |example| + begin + tempfile.write(object_map_data) + tempfile.close + + example.run + ensure + tempfile.unlink + end + end + + it 'removes internal references' do + stub_remote_url_200(url, tempfile.path) + + cleaner.apply_bfg_object_map(object_map) + + aggregate_failures do + clean_refs.each { |ref| expect(repository.ref_exists?(ref)).to be_falsy } + keep_refs.each { |ref| expect(repository.ref_exists?(ref)).to be_truthy } + end end end end diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index a417ef77c9e..8d8eb50ad76 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -709,10 +709,22 @@ describe Gitlab::GitAccess do project.add_developer(user) end - it 'checks LFS integrity only for first change' do - expect_any_instance_of(Gitlab::Checks::LfsIntegrity).to receive(:objects_missing?).exactly(1).times + context 'when LFS is not enabled' do + it 'does not run LFSIntegrity check' do + expect(Gitlab::Checks::LfsIntegrity).not_to receive(:new) - push_access_check + push_access_check + end + end + + context 'when LFS is enabled' do + it 'checks LFS integrity only for first change' do + allow(project).to receive(:lfs_enabled?).and_return(true) + + expect_any_instance_of(Gitlab::Checks::LfsIntegrity).to receive(:objects_missing?).exactly(1).times + + push_access_check + end end end diff --git a/spec/lib/gitlab/gitaly_client/blobs_stitcher_spec.rb b/spec/lib/gitlab/gitaly_client/blobs_stitcher_spec.rb index 9db710e759e..742b2872c40 100644 --- a/spec/lib/gitlab/gitaly_client/blobs_stitcher_spec.rb +++ b/spec/lib/gitlab/gitaly_client/blobs_stitcher_spec.rb @@ -21,7 +21,7 @@ describe Gitlab::GitalyClient::BlobsStitcher do expect(blobs[0].size).to eq(1642) expect(blobs[0].commit_id).to eq('f00ba7') expect(blobs[0].data).to eq("first-line\nsecond-line") - expect(blobs[0].binary?).to be false + expect(blobs[0].binary_in_repo?).to be false expect(blobs[1].id).to eq('abcdef2') expect(blobs[1].mode).to eq('100644') @@ -30,7 +30,7 @@ describe Gitlab::GitalyClient::BlobsStitcher do expect(blobs[1].size).to eq(2461) expect(blobs[1].commit_id).to eq('f00ba8') expect(blobs[1].data).to eq("GIF87a\x90\x01".b) - expect(blobs[1].binary?).to be true + expect(blobs[1].binary_in_repo?).to be true end end end diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb index 5eda4d041a8..e41a75c37a7 100644 --- a/spec/lib/gitlab/gitaly_client_spec.rb +++ b/spec/lib/gitlab/gitaly_client_spec.rb @@ -3,6 +3,20 @@ require 'spec_helper' # We stub Gitaly in `spec/support/gitaly.rb` for other tests. We don't want # those stubs while testing the GitalyClient itself. describe Gitlab::GitalyClient do + let(:sample_cert) { Rails.root.join('spec/fixtures/clusters/sample_cert.pem').to_s } + + before do + allow(described_class) + .to receive(:stub_cert_paths) + .and_return([sample_cert]) + end + + def stub_repos_storages(address) + allow(Gitlab.config.repositories).to receive(:storages).and_return({ + 'default' => { 'gitaly_address' => address } + }) + end + describe '.stub_class' do it 'returns the gRPC health check stub' do expect(described_class.stub_class(:health_check)).to eq(::Grpc::Health::V1::Health::Stub) @@ -15,12 +29,8 @@ describe Gitlab::GitalyClient do describe '.stub_address' do it 'returns the same result after being called multiple times' do - address = 'localhost:9876' - prefixed_address = "tcp://#{address}" - - allow(Gitlab.config.repositories).to receive(:storages).and_return({ - 'default' => { 'gitaly_address' => prefixed_address } - }) + address = 'tcp://localhost:9876' + stub_repos_storages address 2.times do expect(described_class.stub_address('default')).to eq('localhost:9876') @@ -28,6 +38,45 @@ describe Gitlab::GitalyClient do end end + describe '.stub_certs' do + it 'skips certificates if OpenSSLError is raised and report it' do + expect(Rails.logger).to receive(:error).at_least(:once) + expect(Gitlab::Sentry) + .to receive(:track_exception) + .with( + a_kind_of(OpenSSL::X509::CertificateError), + extra: { cert_file: a_kind_of(String) }).at_least(:once) + + expect(OpenSSL::X509::Certificate) + .to receive(:new) + .and_raise(OpenSSL::X509::CertificateError).at_least(:once) + + expect(described_class.stub_certs).to be_a(String) + end + end + describe '.stub_creds' do + it 'returns :this_channel_is_insecure if unix' do + address = 'unix:/tmp/gitaly.sock' + stub_repos_storages address + + expect(described_class.stub_creds('default')).to eq(:this_channel_is_insecure) + end + + it 'returns :this_channel_is_insecure if tcp' do + address = 'tcp://localhost:9876' + stub_repos_storages address + + expect(described_class.stub_creds('default')).to eq(:this_channel_is_insecure) + end + + it 'returns Credentials object if tls' do + address = 'tls://localhost:9876' + stub_repos_storages address + + expect(described_class.stub_creds('default')).to be_a(GRPC::Core::ChannelCredentials) + end + end + describe '.stub' do # Notice that this is referring to gRPC "stubs", not rspec stubs before do @@ -37,9 +86,19 @@ describe Gitlab::GitalyClient do context 'when passed a UNIX socket address' do it 'passes the address as-is to GRPC' do address = 'unix:/tmp/gitaly.sock' - allow(Gitlab.config.repositories).to receive(:storages).and_return({ - 'default' => { 'gitaly_address' => address } - }) + stub_repos_storages address + + expect(Gitaly::CommitService::Stub).to receive(:new).with(address, any_args) + + described_class.stub(:commit_service, 'default') + end + end + + context 'when passed a TLS address' do + it 'strips tls:// prefix before passing it to GRPC::Core::Channel initializer' do + address = 'localhost:9876' + prefixed_address = "tls://#{address}" + stub_repos_storages prefixed_address expect(Gitaly::CommitService::Stub).to receive(:new).with(address, any_args) @@ -51,10 +110,7 @@ describe Gitlab::GitalyClient do it 'strips tcp:// prefix before passing it to GRPC::Core::Channel initializer' do address = 'localhost:9876' prefixed_address = "tcp://#{address}" - - allow(Gitlab.config.repositories).to receive(:storages).and_return({ - 'default' => { 'gitaly_address' => prefixed_address } - }) + stub_repos_storages prefixed_address expect(Gitaly::CommitService::Stub).to receive(:new).with(address, any_args) diff --git a/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb b/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb index efca8564894..25684ea9e2c 100644 --- a/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb @@ -240,12 +240,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi .and_return(user.id) end - # TODO: remove rails5-only after removing rails4 tests - # rails 4 can not handle multiple indexes on the same column set if - # index was added by 't.index' - t.index is used by default in schema.rb in - # rails 5. Let's run this test only in rails 5 env: - # see https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/21492#note_113602758 - it 'returns the existing merge request', :rails5 do + it 'returns the existing merge request' do mr1, exists1 = importer.create_merge_request mr2, exists2 = importer.create_merge_request diff --git a/spec/lib/gitlab/gpg_spec.rb b/spec/lib/gitlab/gpg_spec.rb index 39d09c49989..48bbd7f854c 100644 --- a/spec/lib/gitlab/gpg_spec.rb +++ b/spec/lib/gitlab/gpg_spec.rb @@ -137,7 +137,7 @@ describe Gitlab::Gpg do described_class.using_tmp_keychain do end end - end.not_to raise_error(ThreadError) + end.not_to raise_error end end end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index bae5b21c26f..c8c74883640 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -37,6 +37,7 @@ notes: - events - system_note_metadata - note_diff_file +- suggestions label_links: - target - label @@ -63,6 +64,7 @@ snippets: - award_emoji - user_agent_detail releases: +- author - project project_members: - created_by diff --git a/spec/lib/gitlab/import_export/command_line_util_spec.rb b/spec/lib/gitlab/import_export/command_line_util_spec.rb new file mode 100644 index 00000000000..8e5e0aefac0 --- /dev/null +++ b/spec/lib/gitlab/import_export/command_line_util_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::ImportExport::CommandLineUtil do + include ExportFileHelper + + let(:path) { "#{Dir.tmpdir}/symlink_test" } + let(:archive) { 'spec/fixtures/symlink_export.tar.gz' } + let(:shared) { Gitlab::ImportExport::Shared.new(nil) } + + subject do + Class.new do + include Gitlab::ImportExport::CommandLineUtil + + def initialize + @shared = Gitlab::ImportExport::Shared.new(nil) + end + end.new + end + + before do + FileUtils.mkdir_p(path) + subject.untar_zxf(archive: archive, dir: path) + end + + after do + FileUtils.rm_rf(path) + end + + it 'has the right mask for project.json' do + expect(file_permissions("#{path}/project.json")).to eq(0755) # originally 777 + end + + it 'has the right mask for uploads' do + expect(file_permissions("#{path}/uploads")).to eq(0755) # originally 555 + end +end diff --git a/spec/lib/gitlab/import_export/file_importer_spec.rb b/spec/lib/gitlab/import_export/file_importer_spec.rb index bf34cefe18f..fbc9bcd2df5 100644 --- a/spec/lib/gitlab/import_export/file_importer_spec.rb +++ b/spec/lib/gitlab/import_export/file_importer_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' describe Gitlab::ImportExport::FileImporter do + include ExportFileHelper + let(:shared) { Gitlab::ImportExport::Shared.new(nil) } let(:storage_path) { "#{Dir.tmpdir}/file_importer_spec" } let(:valid_file) { "#{shared.export_path}/valid.json" } @@ -8,6 +10,7 @@ describe Gitlab::ImportExport::FileImporter do let(:hidden_symlink_file) { "#{shared.export_path}/.hidden" } let(:subfolder_symlink_file) { "#{shared.export_path}/subfolder/invalid.json" } let(:evil_symlink_file) { "#{shared.export_path}/.\nevil" } + let(:custom_mode_symlink_file) { "#{shared.export_path}/symlink.mode" } before do stub_const('Gitlab::ImportExport::FileImporter::MAX_RETRIES', 0) @@ -45,10 +48,18 @@ describe Gitlab::ImportExport::FileImporter do expect(File.exist?(subfolder_symlink_file)).to be false end + it 'removes symlinks without any file permissions' do + expect(File.exist?(custom_mode_symlink_file)).to be false + end + it 'does not remove a valid file' do expect(File.exist?(valid_file)).to be true end + it 'does not change a valid file permissions' do + expect(file_permissions(valid_file)).not_to eq(0000) + end + it 'creates the file in the right subfolder' do expect(shared.export_path).to include('test/abcd') end @@ -84,5 +95,7 @@ describe Gitlab::ImportExport::FileImporter do FileUtils.ln_s(valid_file, subfolder_symlink_file) FileUtils.ln_s(valid_file, hidden_symlink_file) FileUtils.ln_s(valid_file, evil_symlink_file) + FileUtils.ln_s(valid_file, custom_mode_symlink_file) + FileUtils.chmod_R(0000, custom_mode_symlink_file) end end diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index d3bfde181bc..24b1f2d995b 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -112,8 +112,11 @@ ProjectSnippet: - visibility_level Release: - id +- name - tag +- sha - description +- author_id - project_id - created_at - updated_at diff --git a/spec/lib/gitlab/json_cache_spec.rb b/spec/lib/gitlab/json_cache_spec.rb new file mode 100644 index 00000000000..b52078e8556 --- /dev/null +++ b/spec/lib/gitlab/json_cache_spec.rb @@ -0,0 +1,401 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::JsonCache do + let(:backend) { double('backend').as_null_object } + let(:namespace) { 'geo' } + let(:key) { 'foo' } + let(:expanded_key) { "#{namespace}:#{key}:#{Rails.version}" } + let(:broadcast_message) { create(:broadcast_message) } + + subject(:cache) { described_class.new(namespace: namespace, backend: backend) } + + describe '#active?' do + context 'when backend respond to active? method' do + it 'delegates to the underlying cache implementation' do + backend = double('backend', active?: false) + + cache = described_class.new(namespace: namespace, backend: backend) + + expect(cache.active?).to eq(false) + end + end + + context 'when backend does not respond to active? method' do + it 'returns true' do + backend = double('backend') + + cache = described_class.new(namespace: namespace, backend: backend) + + expect(cache.active?).to eq(true) + end + end + end + + describe '#cache_key' do + context 'when namespace is not defined' do + it 'expands out the key with Rails version' do + cache = described_class.new(cache_key_with_version: true) + + cache_key = cache.cache_key(key) + + expect(cache_key).to eq("#{key}:#{Rails.version}") + end + end + + context 'when cache_key_with_version is true' do + it 'expands out the key with namespace and Rails version' do + cache = described_class.new(namespace: namespace, cache_key_with_version: true) + + cache_key = cache.cache_key(key) + + expect(cache_key).to eq("#{namespace}:#{key}:#{Rails.version}") + end + end + + context 'when cache_key_with_version is false' do + it 'expands out the key with namespace' do + cache = described_class.new(namespace: namespace, cache_key_with_version: false) + + cache_key = cache.cache_key(key) + + expect(cache_key).to eq("#{namespace}:#{key}") + end + end + + context 'when namespace is nil, and cache_key_with_version is false' do + it 'returns the key' do + cache = described_class.new(namespace: nil, cache_key_with_version: false) + + cache_key = cache.cache_key(key) + + expect(cache_key).to eq(key) + end + end + end + + describe '#expire' do + it 'expires the given key from the cache' do + cache.expire(key) + + expect(backend).to have_received(:delete).with(expanded_key) + end + end + + describe '#read' do + it 'reads the given key from the cache' do + cache.read(key) + + expect(backend).to have_received(:read).with(expanded_key) + end + + it 'returns the cached value when there is data in the cache with the given key' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return("true") + + expect(cache.read(key)).to eq(true) + end + + it 'returns nil when there is no data in the cache with the given key' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return(nil) + + expect(cache.read(key)).to be_nil + end + + context 'when the cached value is a hash' do + it 'parses the cached value' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return(broadcast_message.to_json) + + expect(cache.read(key, BroadcastMessage)).to eq(broadcast_message) + end + + it 'returns nil when klass is nil' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return(broadcast_message.to_json) + + expect(cache.read(key)).to be_nil + end + + it 'gracefully handles bad cached entry' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return('{') + + expect(cache.read(key, BroadcastMessage)).to be_nil + end + + it 'gracefully handles an empty hash' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return('{}') + + expect(cache.read(key, BroadcastMessage)).to be_a(BroadcastMessage) + end + + it 'gracefully handles unknown attributes' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return(broadcast_message.attributes.merge(unknown_attribute: 1).to_json) + + expect(cache.read(key, BroadcastMessage)).to be_nil + end + end + + context 'when the cached value is an array' do + it 'parses the cached value' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return([broadcast_message].to_json) + + expect(cache.read(key, BroadcastMessage)).to eq([broadcast_message]) + end + + it 'returns an empty array when klass is nil' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return([broadcast_message].to_json) + + expect(cache.read(key)).to eq([]) + end + + it 'gracefully handles bad cached entry' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return('[') + + expect(cache.read(key, BroadcastMessage)).to be_nil + end + + it 'gracefully handles an empty array' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return('[]') + + expect(cache.read(key, BroadcastMessage)).to eq([]) + end + + it 'gracefully handles unknown attributes' do + allow(backend).to receive(:read) + .with(expanded_key) + .and_return([{ unknown_attribute: 1 }, broadcast_message.attributes].to_json) + + expect(cache.read(key, BroadcastMessage)).to eq([broadcast_message]) + end + end + end + + describe '#write' do + it 'writes value to the cache with the given key' do + cache.write(key, true) + + expect(backend).to have_received(:write).with(expanded_key, "true", nil) + end + + it 'writes a string containing a JSON representation of the value to the cache' do + cache.write(key, broadcast_message) + + expect(backend).to have_received(:write) + .with(expanded_key, broadcast_message.to_json, nil) + end + + it 'passes options the underlying cache implementation' do + cache.write(key, true, expires_in: 15.seconds) + + expect(backend).to have_received(:write) + .with(expanded_key, "true", expires_in: 15.seconds) + end + + it 'passes options the underlying cache implementation when options is empty' do + cache.write(key, true, {}) + + expect(backend).to have_received(:write) + .with(expanded_key, "true", {}) + end + + it 'passes options the underlying cache implementation when options is nil' do + cache.write(key, true, nil) + + expect(backend).to have_received(:write) + .with(expanded_key, "true", nil) + end + end + + describe '#fetch', :use_clean_rails_memory_store_caching do + let(:backend) { Rails.cache } + + it 'requires a block' do + expect { cache.fetch(key) }.to raise_error(LocalJumpError) + end + + it 'passes options the underlying cache implementation' do + expect(backend).to receive(:write) + .with(expanded_key, "true", expires_in: 15.seconds) + + cache.fetch(key, expires_in: 15.seconds) { true } + end + + context 'when the given key does not exist in the cache' do + context 'when the result of the block is truthy' do + it 'returns the result of the block' do + result = cache.fetch(key) { true } + + expect(result).to eq(true) + end + + it 'caches the value' do + expect(backend).to receive(:write).with(expanded_key, "true", {}) + + cache.fetch(key) { true } + end + end + + context 'when the result of the block is false' do + it 'returns the result of the block' do + result = cache.fetch(key) { false } + + expect(result).to eq(false) + end + + it 'caches the value' do + expect(backend).to receive(:write).with(expanded_key, "false", {}) + + cache.fetch(key) { false } + end + end + + context 'when the result of the block is nil' do + it 'returns the result of the block' do + result = cache.fetch(key) { nil } + + expect(result).to eq(nil) + end + + it 'caches the value' do + expect(backend).to receive(:write).with(expanded_key, "null", {}) + + cache.fetch(key) { nil } + end + end + end + + context 'when the given key exists in the cache' do + context 'when the cached value is a hash' do + before do + backend.write(expanded_key, broadcast_message.to_json) + end + + it 'parses the cached value' do + result = cache.fetch(key, as: BroadcastMessage) { 'block result' } + + expect(result).to eq(broadcast_message) + end + + it "returns the result of the block when 'as' option is nil" do + result = cache.fetch(key, as: nil) { 'block result' } + + expect(result).to eq('block result') + end + + it "returns the result of the block when 'as' option is not informed" do + result = cache.fetch(key) { 'block result' } + + expect(result).to eq('block result') + end + end + + context 'when the cached value is a array' do + before do + backend.write(expanded_key, [broadcast_message].to_json) + end + + it 'parses the cached value' do + result = cache.fetch(key, as: BroadcastMessage) { 'block result' } + + expect(result).to eq([broadcast_message]) + end + + it "returns an empty array when 'as' option is nil" do + result = cache.fetch(key, as: nil) { 'block result' } + + expect(result).to eq([]) + end + + it "returns an empty array when 'as' option is not informed" do + result = cache.fetch(key) { 'block result' } + + expect(result).to eq([]) + end + end + + context 'when the cached value is true' do + before do + backend.write(expanded_key, "true") + end + + it 'returns the cached value' do + result = cache.fetch(key) { 'block result' } + + expect(result).to eq(true) + end + + it 'does not execute the block' do + expect { |block| cache.fetch(key, &block) }.not_to yield_control + end + + it 'does not write to the cache' do + expect(backend).not_to receive(:write) + + cache.fetch(key) { 'block result' } + end + end + + context 'when the cached value is false' do + before do + backend.write(expanded_key, "false") + end + + it 'returns the cached value' do + result = cache.fetch(key) { 'block result' } + + expect(result).to eq(false) + end + + it 'does not execute the block' do + expect { |block| cache.fetch(key, &block) }.not_to yield_control + end + + it 'does not write to the cache' do + expect(backend).not_to receive(:write) + + cache.fetch(key) { 'block result' } + end + end + + context 'when the cached value is nil' do + before do + backend.write(expanded_key, "null") + end + + it 'returns the result of the block' do + result = cache.fetch(key) { 'block result' } + + expect(result).to eq('block result') + end + + it 'writes the result of the block to the cache' do + expect(backend).to receive(:write) + .with(expanded_key, 'block result'.to_json, {}) + + cache.fetch(key) { 'block result' } + end + end + end + end +end diff --git a/spec/lib/gitlab/legacy_github_import/importer_spec.rb b/spec/lib/gitlab/legacy_github_import/importer_spec.rb index d2df21d7bb5..6bc3792eb22 100644 --- a/spec/lib/gitlab/legacy_github_import/importer_spec.rb +++ b/spec/lib/gitlab/legacy_github_import/importer_spec.rb @@ -138,7 +138,7 @@ describe Gitlab::LegacyGithubImport::Importer do let(:release2) do double( - tag_name: 'v2.0.0', + tag_name: 'v1.1.0', name: 'Second release', body: nil, draft: false, diff --git a/spec/lib/gitlab/lfs_token_spec.rb b/spec/lib/gitlab/lfs_token_spec.rb index 77ee30264bf..1ec1ba19e39 100644 --- a/spec/lib/gitlab/lfs_token_spec.rb +++ b/spec/lib/gitlab/lfs_token_spec.rb @@ -1,50 +1,187 @@ +# frozen_string_literal: true + require 'spec_helper' -describe Gitlab::LfsToken do +describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do describe '#token' do shared_examples 'an LFS token generator' do - it 'returns a randomly generated token' do - token = handler.token + it 'returns a computed token' do + expect(Settings).to receive(:attr_encrypted_db_key_base).and_return('fbnbv6hdjweo53qka7kza8v8swxc413c05pb51qgtfte0bygh1p2e508468hfsn5ntmjcyiz7h1d92ashpet5pkdyejg7g8or3yryhuso4h8o5c73h429d9c3r6bjnet').twice + + token = lfs_token.token expect(token).not_to be_nil expect(token).to be_a String - expect(token.length).to eq 50 + expect(described_class.new(actor).token_valid?(token)).to be_truthy + end + end + + context 'when the actor is a user' do + let(:actor) { create(:user, username: 'test_user_lfs_1') } + let(:lfs_token) { described_class.new(actor) } + + before do + allow(actor).to receive(:encrypted_password).and_return('$2a$04$ETfzVS5spE9Hexn9wh6NUenCHG1LyZ2YdciOYxieV1WLSa8DHqOFO') end - it 'returns the correct token based on the key' do - token = handler.token + it_behaves_like 'an LFS token generator' + + it 'returns the correct username' do + expect(lfs_token.actor_name).to eq(actor.username) + end - expect(handler.token).to eq(token) + it 'returns the correct token type' do + expect(lfs_token.type).to eq(:lfs_token) end end - context 'when the actor is a user' do - let(:actor) { create(:user) } - let(:handler) { described_class.new(actor) } + context 'when the actor is a key' do + let(:user) { create(:user, username: 'test_user_lfs_2') } + let(:actor) { create(:key, user: user) } + let(:lfs_token) { described_class.new(actor) } + + before do + allow(user).to receive(:encrypted_password).and_return('$2a$04$C1GAMKsOKouEbhKy2JQoe./3LwOfQAZc.hC8zW2u/wt8xgukvnlV.') + end it_behaves_like 'an LFS token generator' it 'returns the correct username' do - expect(handler.actor_name).to eq(actor.username) + expect(lfs_token.actor_name).to eq(user.username) end it 'returns the correct token type' do - expect(handler.type).to eq(:lfs_token) + expect(lfs_token.type).to eq(:lfs_token) end end context 'when the actor is a deploy key' do + let(:actor_id) { 1 } let(:actor) { create(:deploy_key) } - let(:handler) { described_class.new(actor) } + let(:project) { create(:project) } + let(:lfs_token) { described_class.new(actor) } + + before do + allow(actor).to receive(:id).and_return(actor_id) + end it_behaves_like 'an LFS token generator' it 'returns the correct username' do - expect(handler.actor_name).to eq("lfs+deploy-key-#{actor.id}") + expect(lfs_token.actor_name).to eq("lfs+deploy-key-#{actor_id}") end it 'returns the correct token type' do - expect(handler.type).to eq(:lfs_deploy_token) + expect(lfs_token.type).to eq(:lfs_deploy_token) + end + end + + context 'when the actor is invalid' do + it 'raises an exception' do + expect { described_class.new('invalid') }.to raise_error('Bad Actor') + end + end + end + + describe '#token_valid?' do + let(:actor) { create(:user, username: 'test_user_lfs_1') } + let(:lfs_token) { described_class.new(actor) } + + before do + allow(actor).to receive(:encrypted_password).and_return('$2a$04$ETfzVS5spE9Hexn9wh6NUenCHG1LyZ2YdciOYxieV1WLSa8DHqOFO') + end + + context 'for an HMAC token' do + before do + # We're not interested in testing LegacyRedisDeviseToken here + allow(Gitlab::LfsToken::LegacyRedisDeviseToken).to receive_message_chain(:new, :token_valid?).and_return(false) + end + + context 'where the token is invalid' do + context "because it's junk" do + it 'returns false' do + expect(lfs_token.token_valid?('junk')).to be_falsey + end + end + + context "because it's been fiddled with" do + it 'returns false' do + fiddled_token = lfs_token.token.tap { |token| token[0] = 'E' } + expect(lfs_token.token_valid?(fiddled_token)).to be_falsey + end + end + + context "because it was generated with a different secret" do + it 'returns false' do + different_actor = create(:user, username: 'test_user_lfs_2') + different_secret_token = described_class.new(different_actor).token + expect(lfs_token.token_valid?(different_secret_token)).to be_falsey + end + end + + context "because it's expired" do + it 'returns false' do + expired_token = lfs_token.token + # Needs to be at least 1860 seconds, because the default expiry is + # 1800 seconds with an additional 60 second leeway. + Timecop.freeze(Time.now + 1865) do + expect(lfs_token.token_valid?(expired_token)).to be_falsey + end + end + end + end + + context 'where the token is valid' do + it 'returns true' do + expect(lfs_token.token_valid?(lfs_token.token)).to be_truthy + end + end + end + + context 'for a LegacyRedisDevise token' do + before do + # We're not interested in testing HMACToken here + allow_any_instance_of(Gitlab::LfsToken::HMACToken).to receive(:token_valid?).and_return(false) + end + + context 'where the token is invalid' do + context "because it's junk" do + it 'returns false' do + expect(lfs_token.token_valid?('junk')).to be_falsey + end + end + + context "because it's been fiddled with" do + it 'returns false' do + generated_token = Gitlab::LfsToken::LegacyRedisDeviseToken.new(actor).store_new_token + fiddled_token = generated_token.tap { |token| token[0] = 'E' } + expect(lfs_token.token_valid?(fiddled_token)).to be_falsey + end + end + + context "because it was generated with a different secret" do + it 'returns false' do + different_actor = create(:user, username: 'test_user_lfs_2') + different_secret_token = described_class.new(different_actor).token + expect(lfs_token.token_valid?(different_secret_token)).to be_falsey + end + end + + context "because it's expired" do + it 'returns false' do + generated_token = Gitlab::LfsToken::LegacyRedisDeviseToken.new(actor).store_new_token(1) + # We need a real sleep here because we need to wait for redis to expire the key. + sleep(0.01) + expect(lfs_token.token_valid?(generated_token)).to be_falsey + end + end + end + + context 'where the token is valid' do + it 'returns true' do + generated_token = Gitlab::LfsToken::LegacyRedisDeviseToken.new(actor).store_new_token + expect(lfs_token.token_valid?(generated_token)).to be_truthy + end end end end diff --git a/spec/lib/gitlab/middleware/read_only_spec.rb b/spec/lib/gitlab/middleware/read_only_spec.rb index ac3bc6b2dfe..bdb1f34d2f6 100644 --- a/spec/lib/gitlab/middleware/read_only_spec.rb +++ b/spec/lib/gitlab/middleware/read_only_spec.rb @@ -8,7 +8,6 @@ describe Gitlab::Middleware::ReadOnly do rack = Rack::Builder.new do use ActionDispatch::Session::CacheStore use ActionDispatch::Flash - use ActionDispatch::ParamsParser end rack.run(subject) diff --git a/spec/lib/gitlab/group_hierarchy_spec.rb b/spec/lib/gitlab/object_hierarchy_spec.rb index f3de7adcec7..4700a7ad2e1 100644 --- a/spec/lib/gitlab/group_hierarchy_spec.rb +++ b/spec/lib/gitlab/object_hierarchy_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::GroupHierarchy, :postgresql do +describe Gitlab::ObjectHierarchy, :postgresql do let!(:parent) { create(:group) } let!(:child1) { create(:group, parent: parent) } let!(:child2) { create(:group, parent: child1) } @@ -105,9 +105,9 @@ describe Gitlab::GroupHierarchy, :postgresql do end end - describe '#all_groups' do + describe '#all_objects' do let(:relation) do - described_class.new(Group.where(id: child1.id)).all_groups + described_class.new(Group.where(id: child1.id)).all_objects end it 'includes the base rows' do @@ -123,13 +123,13 @@ describe Gitlab::GroupHierarchy, :postgresql do end it 'uses ancestors_base #initialize argument for ancestors' do - relation = described_class.new(Group.where(id: child1.id), Group.where(id: Group.maximum(:id).succ)).all_groups + relation = described_class.new(Group.where(id: child1.id), Group.where(id: Group.maximum(:id).succ)).all_objects expect(relation).to include(parent) end it 'uses descendants_base #initialize argument for descendants' do - relation = described_class.new(Group.where(id: Group.maximum(:id).succ), Group.where(id: child1.id)).all_groups + relation = described_class.new(Group.where(id: Group.maximum(:id).succ), Group.where(id: child1.id)).all_objects expect(relation).to include(child2) end diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb index 00c62c7bf96..bd0bc2c9044 100644 --- a/spec/lib/gitlab/project_authorizations_spec.rb +++ b/spec/lib/gitlab/project_authorizations_spec.rb @@ -20,7 +20,7 @@ describe Gitlab::ProjectAuthorizations do end let(:authorizations) do - klass = if Group.supports_nested_groups? + klass = if Group.supports_nested_objects? Gitlab::ProjectAuthorizations::WithNestedGroups else Gitlab::ProjectAuthorizations::WithoutNestedGroups @@ -46,7 +46,7 @@ describe Gitlab::ProjectAuthorizations do expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER) end - if Group.supports_nested_groups? + if Group.supports_nested_objects? context 'with nested groups' do let!(:nested_group) { create(:group, parent: group) } let!(:nested_project) { create(:project, namespace: nested_group) } diff --git a/spec/lib/gitlab/prometheus/metric_group_spec.rb b/spec/lib/gitlab/prometheus/metric_group_spec.rb index e7d16e73663..5cc6827488b 100644 --- a/spec/lib/gitlab/prometheus/metric_group_spec.rb +++ b/spec/lib/gitlab/prometheus/metric_group_spec.rb @@ -21,6 +21,13 @@ describe Gitlab::Prometheus::MetricGroup do common_metric_group_a.id, common_metric_group_b_q1.id, common_metric_group_b_q2.id) end + + it 'orders by priority' do + priorities = subject.map(&:priority) + names = subject.map(&:name) + expect(priorities).to eq([10, 5]) + expect(names).to eq(['Response metrics (AWS ELB)', 'System metrics (Kubernetes)']) + end end describe '.for_project' do diff --git a/spec/lib/gitlab/prometheus/query_variables_spec.rb b/spec/lib/gitlab/prometheus/query_variables_spec.rb index 78974cadb69..78c74266c61 100644 --- a/spec/lib/gitlab/prometheus/query_variables_spec.rb +++ b/spec/lib/gitlab/prometheus/query_variables_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' describe Gitlab::Prometheus::QueryVariables do describe '.call' do - set(:environment) { create(:environment) } + let(:environment) { create(:environment) } let(:slug) { environment.slug } subject { described_class.call(environment) } @@ -20,7 +20,7 @@ describe Gitlab::Prometheus::QueryVariables do it { is_expected.to include(kube_namespace: '') } end - context 'with deplyoment platform' do + context 'with deployment platform' do let(:kube_namespace) { environment.deployment_platform.actual_namespace } before do diff --git a/spec/lib/gitlab/safe_request_store_spec.rb b/spec/lib/gitlab/safe_request_store_spec.rb index c797171dbe2..bae87e43615 100644 --- a/spec/lib/gitlab/safe_request_store_spec.rb +++ b/spec/lib/gitlab/safe_request_store_spec.rb @@ -78,6 +78,12 @@ describe Gitlab::SafeRequestStore do described_class.write('foo', true) end.to change { described_class.read('foo') }.from(nil).to(true) end + + it 'does not pass the options hash to the underlying store implementation' do + expect(described_class.store).to receive(:write).with('foo', true) + + described_class.write('foo', true, expires_in: 15.seconds) + end end context 'when RequestStore is NOT active' do @@ -86,6 +92,12 @@ describe Gitlab::SafeRequestStore do described_class.write('foo', true) end.not_to change { described_class.read('foo') }.from(nil) end + + it 'does not pass the options hash to the underlying store implementation' do + expect(described_class.store).to receive(:write).with('foo', true) + + described_class.write('foo', true, expires_in: 15.seconds) + end end end diff --git a/spec/lib/gitlab/sql/glob_spec.rb b/spec/lib/gitlab/sql/glob_spec.rb index 1cf8935bfe3..3147b52dcc5 100644 --- a/spec/lib/gitlab/sql/glob_spec.rb +++ b/spec/lib/gitlab/sql/glob_spec.rb @@ -35,9 +35,8 @@ describe Gitlab::SQL::Glob do value = query("SELECT #{quote(string)} LIKE #{pattern}") .rows.flatten.first - check = Gitlab.rails5? ? true : 't' case value - when check, 1 + when true, 1 true else false diff --git a/spec/lib/gitlab/upgrader_spec.rb b/spec/lib/gitlab/upgrader_spec.rb deleted file mode 100644 index 6106f13c774..00000000000 --- a/spec/lib/gitlab/upgrader_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Upgrader do - let(:upgrader) { described_class.new } - let(:current_version) { Gitlab::VERSION } - - describe 'current_version_raw' do - it { expect(upgrader.current_version_raw).to eq(current_version) } - end - - describe 'latest_version?' do - it 'is true if newest version' do - allow(upgrader).to receive(:latest_version_raw).and_return(current_version) - expect(upgrader.latest_version?).to be_truthy - end - end - - describe 'latest_version_raw' do - it 'is the latest version for GitLab 5' do - allow(upgrader).to receive(:current_version_raw).and_return("5.3.0") - expect(upgrader.latest_version_raw).to eq("v5.4.2") - end - - it 'gets the latest version from tags' do - allow(upgrader).to receive(:fetch_git_tags).and_return([ - '6f0733310546402c15d3ae6128a95052f6c8ea96 refs/tags/v7.1.1', - 'facfec4b242ce151af224e20715d58e628aa5e74 refs/tags/v7.1.1^{}', - 'f7068d99c79cf79befbd388030c051bb4b5e86d4 refs/tags/v7.10.4', - '337225a4fcfa9674e2528cb6d41c46556bba9dfa refs/tags/v7.10.4^{}', - '880e0ba0adbed95d087f61a9a17515e518fc6440 refs/tags/v7.11.1', - '6584346b604f981f00af8011cd95472b2776d912 refs/tags/v7.11.1^{}', - '43af3e65a486a9237f29f56d96c3b3da59c24ae0 refs/tags/v7.11.2', - 'dac18e7728013a77410e926a1e64225703754a2d refs/tags/v7.11.2^{}', - '0bf21fd4b46c980c26fd8c90a14b86a4d90cc950 refs/tags/v7.9.4', - 'b10de29edbaff7219547dc506cb1468ee35065c3 refs/tags/v7.9.4^{}' - ]) - expect(upgrader.latest_version_raw).to eq("v7.11.2") - end - end -end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index deb19fe1a4b..2a09f581f68 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -117,6 +117,7 @@ describe Gitlab::UsageData do releases remote_mirrors snippets + suggestions todos uploads web_hooks diff --git a/spec/lib/gitlab/utils/override_spec.rb b/spec/lib/gitlab/utils/override_spec.rb index fc08ebcfc6d..9e7c97f8095 100644 --- a/spec/lib/gitlab/utils/override_spec.rb +++ b/spec/lib/gitlab/utils/override_spec.rb @@ -25,11 +25,21 @@ describe Gitlab::Utils::Override do let(:klass) { subject } - def good(mod) + def good(mod, bad_arity: false, negative_arity: false) mod.module_eval do override :good - def good - super.succ + + if bad_arity + def good(num) + end + elsif negative_arity + def good(*args) + super.succ + end + else + def good + super.succ + end end end @@ -56,6 +66,14 @@ describe Gitlab::Utils::Override do described_class.verify! end + it 'checks ok for overriding method using negative arity' do + good(subject, negative_arity: true) + result = instance.good + + expect(result).to eq(1) + described_class.verify! + end + it 'raises NotImplementedError when it is not overriding anything' do expect do bad(subject) @@ -63,6 +81,14 @@ describe Gitlab::Utils::Override do described_class.verify! end.to raise_error(NotImplementedError) end + + it 'raises NotImplementedError when overriding a method with different arity' do + expect do + good(subject, bad_arity: true) + instance.good(1) + described_class.verify! + end.to raise_error(NotImplementedError) + end end shared_examples 'checking as intended, nothing was overridden' do diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb index b3f55a2e1bd..7213eee5675 100644 --- a/spec/lib/gitlab/workhorse_spec.rb +++ b/spec/lib/gitlab/workhorse_spec.rb @@ -246,7 +246,6 @@ describe Gitlab::Workhorse do GL_ID: "user-#{user.id}", GL_USERNAME: user.username, GL_REPOSITORY: "project-#{project.id}", - RepoPath: repo_path, ShowAllRefs: false } end @@ -261,7 +260,6 @@ describe Gitlab::Workhorse do GL_ID: "user-#{user.id}", GL_USERNAME: user.username, GL_REPOSITORY: "wiki-#{project.id}", - RepoPath: repo_path, ShowAllRefs: false } end diff --git a/spec/lib/json_web_token/rsa_token_spec.rb b/spec/lib/json_web_token/rsa_token_spec.rb index d6edc964844..a3c54651e80 100644 --- a/spec/lib/json_web_token/rsa_token_spec.rb +++ b/spec/lib/json_web_token/rsa_token_spec.rb @@ -25,7 +25,7 @@ describe JSONWebToken::RSAToken do rsa_token['key'] = 'value' end - subject { JWT.decode(rsa_encoded, rsa_key) } + subject { JWT.decode(rsa_encoded, rsa_key, true, { algorithm: 'RS256' }) } it { expect {subject}.not_to raise_error } it { expect(subject.first).to include('key' => 'value') } @@ -39,7 +39,7 @@ describe JSONWebToken::RSAToken do context 'for invalid key to raise an exception' do let(:new_key) { OpenSSL::PKey::RSA.generate(512) } - subject { JWT.decode(rsa_encoded, new_key) } + subject { JWT.decode(rsa_encoded, new_key, true, { algorithm: 'RS256' }) } it { expect {subject}.to raise_error(JWT::DecodeError) } end diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb index f18f97a9c6a..77fea5b2d24 100644 --- a/spec/lib/mattermost/session_spec.rb +++ b/spec/lib/mattermost/session_spec.rb @@ -67,11 +67,13 @@ describe Mattermost::Session, type: :request do .with(query: hash_including({ 'state' => state })) .to_return do |request| post "/oauth/token", - client_id: doorkeeper.uid, - client_secret: doorkeeper.secret, - redirect_uri: params[:redirect_uri], - grant_type: 'authorization_code', - code: request.uri.query_values['code'] + params: { + client_id: doorkeeper.uid, + client_secret: doorkeeper.secret, + redirect_uri: params[:redirect_uri], + grant_type: 'authorization_code', + code: request.uri.query_values['code'] + } if response.status == 200 { headers: { 'token' => 'thisworksnow' }, status: 202 } diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 1d17aec0ded..f2d99872401 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -4,6 +4,7 @@ require 'email_spec' describe Notify do include EmailSpec::Helpers include EmailSpec::Matchers + include EmailHelpers include RepoHelpers include_context 'gitlab email notification' @@ -27,15 +28,6 @@ describe Notify do description: 'My awesome description!') end - def have_referable_subject(referable, reply: false) - prefix = (referable.project ? "#{referable.project.name} | " : '').freeze - prefix = "Re: #{prefix}" if reply - - suffix = "#{referable.title} (#{referable.to_reference})" - - have_subject [prefix, suffix].compact.join - end - context 'for a project' do shared_examples 'an assignee email' do it 'is sent to the assignee as the author' do @@ -898,22 +890,14 @@ describe Notify do shared_examples 'an email for a note on a diff discussion' do |model| let(:note) { create(model, author: note_author) } - context 'when note is on image' do + context 'when note is not on text' do before do - allow_any_instance_of(DiffDiscussion).to receive(:on_image?).and_return(true) + allow_any_instance_of(DiffDiscussion).to receive(:on_text?).and_return(false) end it 'does not include diffs with character-level highlighting' do is_expected.not_to have_body_text '<span class="p">}</span></span>' end - - it 'ends the intro with a dot' do - is_expected.to have_body_text "#{note.diff_file.file_path}</a>." - end - end - - it 'ends the intro with a colon' do - is_expected.to have_body_text "#{note.diff_file.file_path}</a>:" end it 'includes diffs with character-level highlighting' do diff --git a/spec/migrations/backfill_releases_name_with_tag_name_spec.rb b/spec/migrations/backfill_releases_name_with_tag_name_spec.rb new file mode 100644 index 00000000000..6f436de84b7 --- /dev/null +++ b/spec/migrations/backfill_releases_name_with_tag_name_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20181212104941_backfill_releases_name_with_tag_name.rb') + +describe BackfillReleasesNameWithTagName, :migration do + let(:releases) { table(:releases) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + + let(:namespace) { namespaces.create(name: 'foo', path: 'foo') } + let(:project) { projects.create!(namespace_id: namespace.id) } + let(:release) { releases.create!(project_id: project.id, tag: 'v1.0.0') } + + it 'defaults name to tag value' do + expect(release.tag).to be_present + + migrate! + + release.reload + expect(release.name).to eq(release.tag) + end +end diff --git a/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb b/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb new file mode 100644 index 00000000000..b2d8f476bb2 --- /dev/null +++ b/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20181219145520_migrate_cluster_configure_worker_sidekiq_queue.rb') + +describe MigrateClusterConfigureWorkerSidekiqQueue, :sidekiq, :redis do + include Gitlab::Database::MigrationHelpers + + context 'when there are jobs in the queue' do + it 'correctly migrates queue when migrating up' do + Sidekiq::Testing.disable! do + stubbed_worker(queue: 'gcp_cluster:cluster_platform_configure').perform_async('Something', [1]) + stubbed_worker(queue: 'gcp_cluster:cluster_configure').perform_async('Something', [1]) + + described_class.new.up + + expect(sidekiq_queue_length('gcp_cluster:cluster_platform_configure')).to eq 0 + expect(sidekiq_queue_length('gcp_cluster:cluster_configure')).to eq 2 + end + end + + it 'does not affect other queues under the same namespace' do + Sidekiq::Testing.disable! do + stubbed_worker(queue: 'gcp_cluster:cluster_install_app').perform_async('Something', [1]) + stubbed_worker(queue: 'gcp_cluster:cluster_provision').perform_async('Something', [1]) + stubbed_worker(queue: 'gcp_cluster:cluster_wait_for_app_installation').perform_async('Something', [1]) + stubbed_worker(queue: 'gcp_cluster:wait_for_cluster_creation').perform_async('Something', [1]) + stubbed_worker(queue: 'gcp_cluster:cluster_wait_for_ingress_ip_address').perform_async('Something', [1]) + stubbed_worker(queue: 'gcp_cluster:cluster_project_configure').perform_async('Something', [1]) + + described_class.new.up + + expect(sidekiq_queue_length('gcp_cluster:cluster_install_app')).to eq 1 + expect(sidekiq_queue_length('gcp_cluster:cluster_provision')).to eq 1 + expect(sidekiq_queue_length('gcp_cluster:cluster_wait_for_app_installation')).to eq 1 + expect(sidekiq_queue_length('gcp_cluster:wait_for_cluster_creation')).to eq 1 + expect(sidekiq_queue_length('gcp_cluster:cluster_wait_for_ingress_ip_address')).to eq 1 + expect(sidekiq_queue_length('gcp_cluster:cluster_project_configure')).to eq 1 + end + end + + it 'correctly migrates queue when migrating down' do + Sidekiq::Testing.disable! do + stubbed_worker(queue: 'gcp_cluster:cluster_configure').perform_async('Something', [1]) + + described_class.new.down + + expect(sidekiq_queue_length('gcp_cluster:cluster_platform_configure')).to eq 1 + expect(sidekiq_queue_length('gcp_cluster:cluster_configure')).to eq 0 + end + end + end + + context 'when there are no jobs in the queues' do + it 'does not raise error when migrating up' do + expect { described_class.new.up }.not_to raise_error + end + + it 'does not raise error when migrating down' do + expect { described_class.new.down }.not_to raise_error + end + end + + def stubbed_worker(queue:) + Class.new do + include Sidekiq::Worker + sidekiq_options queue: queue + end + end +end diff --git a/spec/models/appearance_spec.rb b/spec/models/appearance_spec.rb index 35415030154..ec2e7d672f0 100644 --- a/spec/models/appearance_spec.rb +++ b/spec/models/appearance_spec.rb @@ -26,4 +26,34 @@ describe Appearance do let(:uploader_class) { AttachmentUploader } end end + + shared_examples 'logo paths' do |logo_type| + let(:appearance) { create(:appearance, "with_#{logo_type}".to_sym) } + let(:filename) { 'dk.png' } + let(:expected_path) { "/uploads/-/system/appearance/#{logo_type}/#{appearance.id}/#{filename}" } + + it 'returns nil when there is no upload' do + expect(subject.send("#{logo_type}_path")).to be_nil + end + + it 'returns a local path using the system route' do + expect(appearance.send("#{logo_type}_path")).to eq(expected_path) + end + + describe 'with asset host configured' do + let(:asset_host) { 'https://gitlab-assets.example.com' } + + before do + allow(ActionController::Base).to receive(:asset_host) { asset_host } + end + + it 'returns a full URL with the system path' do + expect(appearance.send("#{logo_type}_path")).to eq("#{asset_host}#{expected_path}") + end + end + end + + %i(logo header_logo favicon).each do |logo_type| + it_behaves_like 'logo paths', logo_type + end end diff --git a/spec/models/blob_spec.rb b/spec/models/blob_spec.rb index e8c03b587e2..05cf242e84d 100644 --- a/spec/models/blob_spec.rb +++ b/spec/models/blob_spec.rb @@ -122,14 +122,14 @@ describe Blob do end end - describe '#raw_binary?' do + describe '#binary?' do context 'if the blob is stored externally' do context 'if the extension has a rich viewer' do context 'if the viewer is binary' do it 'returns true' do blob = fake_blob(path: 'file.pdf', lfs: true) - expect(blob.raw_binary?).to be_truthy + expect(blob.binary?).to be_truthy end end @@ -137,7 +137,7 @@ describe Blob do it 'return false' do blob = fake_blob(path: 'file.md', lfs: true) - expect(blob.raw_binary?).to be_falsey + expect(blob.binary?).to be_falsey end end end @@ -148,7 +148,7 @@ describe Blob do it 'returns false' do blob = fake_blob(path: 'file.txt', lfs: true) - expect(blob.raw_binary?).to be_falsey + expect(blob.binary?).to be_falsey end end @@ -156,7 +156,7 @@ describe Blob do it 'returns false' do blob = fake_blob(path: 'file.ics', lfs: true) - expect(blob.raw_binary?).to be_falsey + expect(blob.binary?).to be_falsey end end end @@ -166,7 +166,7 @@ describe Blob do it 'returns false' do blob = fake_blob(path: 'file.rb', lfs: true) - expect(blob.raw_binary?).to be_falsey + expect(blob.binary?).to be_falsey end end @@ -174,7 +174,7 @@ describe Blob do it 'returns true' do blob = fake_blob(path: 'file.exe', lfs: true) - expect(blob.raw_binary?).to be_truthy + expect(blob.binary?).to be_truthy end end end @@ -184,7 +184,7 @@ describe Blob do it 'returns false' do blob = fake_blob(path: 'file.ini', lfs: true) - expect(blob.raw_binary?).to be_falsey + expect(blob.binary?).to be_falsey end end @@ -192,7 +192,7 @@ describe Blob do it 'returns true' do blob = fake_blob(path: 'file.wtf', lfs: true) - expect(blob.raw_binary?).to be_truthy + expect(blob.binary?).to be_truthy end end end @@ -204,7 +204,7 @@ describe Blob do it 'returns true' do blob = fake_blob(path: 'file.pdf', binary: true) - expect(blob.raw_binary?).to be_truthy + expect(blob.binary?).to be_truthy end end @@ -212,7 +212,7 @@ describe Blob do it 'return false' do blob = fake_blob(path: 'file.md') - expect(blob.raw_binary?).to be_falsey + expect(blob.binary?).to be_falsey end end end diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb index d6e5b557870..89839709131 100644 --- a/spec/models/broadcast_message_spec.rb +++ b/spec/models/broadcast_message_spec.rb @@ -49,7 +49,7 @@ describe BroadcastMessage do it 'caches the output of the query' do create(:broadcast_message) - expect(described_class).to receive(:where).and_call_original.once + expect(described_class).to receive(:current_and_future_messages).and_call_original.once described_class.current @@ -93,27 +93,6 @@ describe BroadcastMessage do expect(Rails.cache).to receive(:delete).with(described_class::LEGACY_CACHE_KEY) expect(described_class.current.length).to eq(0) end - - it 'gracefully handles bad cache entry' do - allow(described_class).to receive(:current_and_future_messages).and_return('{') - - expect(described_class.current).to be_empty - end - - it 'gracefully handles an empty hash' do - allow(described_class).to receive(:current_and_future_messages).and_return('{}') - - expect(described_class.current).to be_empty - end - - it 'gracefully handles unknown attributes' do - message = create(:broadcast_message) - - allow(described_class).to receive(:current_and_future_messages) - .and_return([{ bad_attr: 1 }, message]) - - expect(described_class.current).to eq([message]) - end end describe '#active?' do diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb new file mode 100644 index 00000000000..741cdfef1a5 --- /dev/null +++ b/spec/models/ci/bridge_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe Ci::Bridge do + set(:project) { create(:project) } + set(:pipeline) { create(:ci_pipeline, project: project) } + + let(:bridge) do + create(:ci_bridge, pipeline: pipeline) + end + + describe '#tags' do + it 'only has a bridge tag' do + expect(bridge.tags).to eq [:bridge] + end + end + + describe '#detailed_status' do + let(:user) { create(:user) } + let(:status) { bridge.detailed_status(user) } + + it 'returns detailed status object' do + expect(status).to be_a Gitlab::Ci::Status::Success + end + end +end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 89f78f629d4..fe7f5f8e1e3 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -2114,6 +2114,7 @@ describe Ci::Build do { key: 'CI_JOB_NAME', value: 'test', public: true }, { key: 'CI_JOB_STAGE', value: 'test', public: true }, { key: 'CI_COMMIT_SHA', value: build.sha, public: true }, + { key: 'CI_COMMIT_SHORT_SHA', value: build.short_sha, public: true }, { key: 'CI_COMMIT_BEFORE_SHA', value: build.before_sha, public: true }, { key: 'CI_COMMIT_REF_NAME', value: build.ref, public: true }, { key: 'CI_COMMIT_REF_SLUG', value: build.ref_slug, public: true }, @@ -2725,6 +2726,7 @@ describe Ci::Build do it 'returns static predefined variables' do keys = %w[CI_JOB_NAME CI_COMMIT_SHA + CI_COMMIT_SHORT_SHA CI_COMMIT_REF_NAME CI_COMMIT_REF_SLUG CI_JOB_STAGE] diff --git a/spec/models/clusters/applications/cert_manager_spec.rb b/spec/models/clusters/applications/cert_manager_spec.rb index 170c6001eaf..e825f3e2392 100644 --- a/spec/models/clusters/applications/cert_manager_spec.rb +++ b/spec/models/clusters/applications/cert_manager_spec.rb @@ -14,7 +14,7 @@ describe Clusters::Applications::CertManager do let(:application) { create(:clusters_applications_cert_managers, :scheduled, version: 'v0.4.0') } it 'updates the application version' do - expect(application.reload.version).to eq('v0.5.0') + expect(application.reload.version).to eq('v0.5.2') end end end @@ -28,7 +28,7 @@ describe Clusters::Applications::CertManager do it 'should be initialized with cert_manager arguments' do expect(subject.name).to eq('certmanager') expect(subject.chart).to eq('stable/cert-manager') - expect(subject.version).to eq('v0.5.0') + expect(subject.version).to eq('v0.5.2') expect(subject).not_to be_rbac expect(subject.files).to eq(cert_manager.files.merge(cluster_issuer_file)) expect(subject.postinstall).to eq(['/usr/bin/kubectl create -f /data/helm/certmanager/config/cluster_issuer.yaml']) @@ -57,7 +57,7 @@ describe Clusters::Applications::CertManager do let(:cert_manager) { create(:clusters_applications_cert_managers, :errored, version: '0.0.1') } it 'should be initialized with the locked version' do - expect(subject.version).to eq('v0.5.0') + expect(subject.version).to eq('v0.5.2') end end end diff --git a/spec/models/clusters/applications/knative_spec.rb b/spec/models/clusters/applications/knative_spec.rb index a1579b90436..809880f5969 100644 --- a/spec/models/clusters/applications/knative_spec.rb +++ b/spec/models/clusters/applications/knative_spec.rb @@ -33,10 +33,10 @@ describe Clusters::Applications::Knative do end context 'application install previously errored with older version' do - let(:application) { create(:clusters_applications_knative, :scheduled, version: '0.1.3') } + let(:application) { create(:clusters_applications_knative, :scheduled, version: '0.2.2') } it 'updates the application version' do - expect(application.reload.version).to eq('0.1.3') + expect(application.reload.version).to eq('0.2.2') end end end @@ -105,7 +105,7 @@ describe Clusters::Applications::Knative do it 'should be initialized with knative arguments' do expect(subject.name).to eq('knative') expect(subject.chart).to eq('knative/knative') - expect(subject.version).to eq('0.1.3') + expect(subject.version).to eq('0.2.2') expect(subject.files).to eq(knative.files) end end diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index 062d2fd0768..e6b076adc76 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -325,12 +325,13 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching context 'with valid pods' do let(:pod) { kube_pod(app: environment.slug) } + let(:pod_with_no_terminal) { kube_pod(app: environment.slug, status: "Pending") } let(:terminals) { kube_terminals(service, pod) } before do stub_reactive_cache( service, - pods: [pod, pod, kube_pod(app: "should-be-filtered-out")] + pods: [pod, pod, pod_with_no_terminal, kube_pod(app: "should-be-filtered-out")] ) end @@ -394,7 +395,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching context 'when namespace is updated' do it 'should call ConfigureWorker' do - expect(ClusterPlatformConfigureWorker).to receive(:perform_async).with(cluster.id).once + expect(ClusterConfigureWorker).to receive(:perform_async).with(cluster.id).once platform.namespace = 'new-namespace' platform.save @@ -403,7 +404,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching context 'when namespace is not updated' do it 'should not call ConfigureWorker' do - expect(ClusterPlatformConfigureWorker).not_to receive(:perform_async) + expect(ClusterConfigureWorker).not_to receive(:perform_async) platform.username = "new-username" platform.save diff --git a/spec/models/concerns/avatarable_spec.rb b/spec/models/concerns/avatarable_spec.rb index 7d617cb7b19..1ea7f2b9985 100644 --- a/spec/models/concerns/avatarable_spec.rb +++ b/spec/models/concerns/avatarable_spec.rb @@ -33,6 +33,43 @@ describe Avatarable do end describe '#avatar_path' do + context 'with caching enabled', :request_store do + let!(:avatar_path) { [relative_url_root, project.avatar.local_url].join } + let!(:avatar_url) { [gitlab_host, relative_url_root, project.avatar.local_url].join } + + it 'only calls local_url once' do + expect(project.avatar).to receive(:local_url).once.and_call_original + + 2.times do + expect(project.avatar_path).to eq(avatar_path) + end + end + + it 'calls local_url twice for path and URLs' do + expect(project.avatar).to receive(:local_url).exactly(2).times.and_call_original + + expect(project.avatar_path(only_path: true)).to eq(avatar_path) + expect(project.avatar_path(only_path: false)).to eq(avatar_url) + end + + it 'calls local_url twice for different sizes' do + expect(project.avatar).to receive(:local_url).exactly(2).times.and_call_original + + expect(project.avatar_path).to eq(avatar_path) + expect(project.avatar_path(size: 40)).to eq(avatar_path + "?width=40") + end + + it 'handles unpersisted objects' do + new_project = build(:project, :with_avatar) + path = [relative_url_root, new_project.avatar.local_url].join + expect(new_project.avatar).to receive(:local_url).exactly(2).times.and_call_original + + 2.times do + expect(new_project.avatar_path).to eq(path) + end + end + end + using RSpec::Parameterized::TableSyntax where(:has_asset_host, :visibility_level, :only_path, :avatar_path_prefix) do diff --git a/spec/models/concerns/cacheable_attributes_spec.rb b/spec/models/concerns/cacheable_attributes_spec.rb index 827fbc9d7d5..689e7d3058f 100644 --- a/spec/models/concerns/cacheable_attributes_spec.rb +++ b/spec/models/concerns/cacheable_attributes_spec.rb @@ -20,6 +20,10 @@ describe CacheableAttributes do @_last ||= new('foo' => 'a', 'bar' => 'b') end + def self.column_names + %w[foo bar baz] + end + attr_accessor :attributes def initialize(attrs = {}, *) @@ -75,13 +79,13 @@ describe CacheableAttributes do context 'without any attributes given' do it 'intializes a new object with the defaults' do - expect(minimal_test_class.build_from_defaults.attributes).to eq(minimal_test_class.defaults) + expect(minimal_test_class.build_from_defaults.attributes).to eq(minimal_test_class.defaults.stringify_keys) end end context 'with attributes given' do it 'intializes a new object with the given attributes merged into the defaults' do - expect(minimal_test_class.build_from_defaults(foo: 'd').attributes[:foo]).to eq('d') + expect(minimal_test_class.build_from_defaults(foo: 'd').attributes['foo']).to eq('d') end end diff --git a/spec/models/concerns/chronic_duration_attribute_spec.rb b/spec/models/concerns/chronic_duration_attribute_spec.rb index b14b773b653..51221e07ca3 100644 --- a/spec/models/concerns/chronic_duration_attribute_spec.rb +++ b/spec/models/concerns/chronic_duration_attribute_spec.rb @@ -43,7 +43,7 @@ shared_examples 'ChronicDurationAttribute writer' do end it "doesn't raise exception" do - expect { subject.send("#{virtual_field}=", '-10m') }.not_to raise_error(ChronicDuration::DurationParseError) + expect { subject.send("#{virtual_field}=", '-10m') }.not_to raise_error end it "doesn't change value" do @@ -87,7 +87,7 @@ shared_examples 'ChronicDurationAttribute writer' do end it "doesn't raise exception" do - expect { subject.send("#{virtual_field}=", nil) }.not_to raise_error(NoMethodError) + expect { subject.send("#{virtual_field}=", nil) }.not_to raise_error end end end diff --git a/spec/models/concerns/discussion_on_diff_spec.rb b/spec/models/concerns/discussion_on_diff_spec.rb index 73eb7a1160d..4b16e6e3902 100644 --- a/spec/models/concerns/discussion_on_diff_spec.rb +++ b/spec/models/concerns/discussion_on_diff_spec.rb @@ -50,11 +50,17 @@ describe DiscussionOnDiff do end context "when the diff line does not exist on a legacy diff note" do + subject { create(:legacy_diff_note_on_merge_request).to_discussion } + it "returns an empty array" do - legacy_note = LegacyDiffNote.new + expect(truncated_lines).to eq([]) + end + end - allow(subject).to receive(:first_note).and_return(legacy_note) + context 'when the discussion is on an image' do + subject { create(:image_diff_note_on_merge_request).to_discussion } + it 'returns an empty array' do expect(truncated_lines).to eq([]) end end diff --git a/spec/models/diff_note_spec.rb b/spec/models/diff_note_spec.rb index 8624f0daa4d..fda00a693f0 100644 --- a/spec/models/diff_note_spec.rb +++ b/spec/models/diff_note_spec.rb @@ -318,25 +318,28 @@ describe DiffNote do end end - describe "image diff notes" do - let(:path) { "files/images/any_image.png" } + describe '#supports_suggestion?' do + context 'when noteable does not support suggestions' do + it 'returns false' do + allow(subject.noteable).to receive(:supports_suggestion?) { false } - let!(:position) do - Gitlab::Diff::Position.new( - old_path: path, - new_path: path, - width: 10, - height: 10, - x: 1, - y: 1, - diff_refs: merge_request.diff_refs, - position_type: "image" - ) + expect(subject.supports_suggestion?).to be(false) + end end - describe "validations" do - subject { build(:diff_note_on_merge_request, project: project, position: position, noteable: merge_request) } + context 'when line is not suggestible' do + it 'returns false' do + allow_any_instance_of(Gitlab::Diff::Line).to receive(:suggestible?) { false } + + expect(subject.supports_suggestion?).to be(false) + end + end + end + describe "image diff notes" do + subject { build(:image_diff_note_on_merge_request, project: project, noteable: merge_request) } + + describe "validations" do it { is_expected.not_to validate_presence_of(:line_code) } it "does not validate diff line" do diff --git a/spec/models/diff_viewer/base_spec.rb b/spec/models/diff_viewer/base_spec.rb index c90b32c5d77..f4efe5a7b3a 100644 --- a/spec/models/diff_viewer/base_spec.rb +++ b/spec/models/diff_viewer/base_spec.rb @@ -58,7 +58,7 @@ describe DiffViewer::Base do context 'when the binaryness does not match' do before do - allow_any_instance_of(Blob).to receive(:binary?).and_return(true) + allow_any_instance_of(Blob).to receive(:binary_in_repo?).and_return(true) end it 'returns false' do @@ -141,4 +141,25 @@ describe DiffViewer::Base do end end end + + describe '#render_error_message' do + it 'returns nothing when no render_error' do + expect(viewer.render_error).to be_nil + expect(viewer.render_error_message).to be_nil + end + + context 'when render_error error' do + before do + allow(viewer).to receive(:render_error).and_return(:too_large) + end + + it 'returns an error message' do + expect(viewer.render_error_message).to include('it is too large') + end + + it 'includes a "view the blob" link' do + expect(viewer.render_error_message).to include('view the blob') + end + end + end end diff --git a/spec/models/diff_viewer/server_side_spec.rb b/spec/models/diff_viewer/server_side_spec.rb index 98a8f6d4cc9..86b14b6ebf3 100644 --- a/spec/models/diff_viewer/server_side_spec.rb +++ b/spec/models/diff_viewer/server_side_spec.rb @@ -32,4 +32,24 @@ describe DiffViewer::ServerSide do end end end + + describe '#render_error_reason' do + context 'when the diff file is stored externally' do + before do + allow(diff_file).to receive(:stored_externally?).and_return(true) + end + + it 'returns error message if stored in LFS' do + allow(diff_file).to receive(:external_storage).and_return(:lfs) + + expect(subject.render_error_message).to include('it is stored in LFS') + end + + it 'returns error message if stored externally' do + allow(diff_file).to receive(:external_storage).and_return(:foo) + + expect(subject.render_error_message).to include('it is stored externally') + end + end + end end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 81748681528..a64720f1876 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -243,6 +243,20 @@ describe Event do expect(event.visible_to_user?(admin)).to eq true end end + + context 'private project' do + let(:project) { create(:project, :private) } + let(:target) { note_on_issue } + + it do + expect(event.visible_to_user?(non_member)).to eq false + expect(event.visible_to_user?(author)).to eq false + expect(event.visible_to_user?(assignee)).to eq false + expect(event.visible_to_user?(member)).to eq true + expect(event.visible_to_user?(guest)).to eq true + expect(event.visible_to_user?(admin)).to eq true + end + end end context 'merge request diff note event' do @@ -265,8 +279,8 @@ describe Event do it do expect(event.visible_to_user?(non_member)).to eq false - expect(event.visible_to_user?(author)).to eq true - expect(event.visible_to_user?(assignee)).to eq true + expect(event.visible_to_user?(author)).to eq false + expect(event.visible_to_user?(assignee)).to eq false expect(event.visible_to_user?(member)).to eq true expect(event.visible_to_user?(guest)).to eq false expect(event.visible_to_user?(admin)).to eq true diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb index cbe60b3a4a5..33e984dc399 100644 --- a/spec/models/merge_request_diff_spec.rb +++ b/spec/models/merge_request_diff_spec.rb @@ -105,7 +105,7 @@ describe MergeRequestDiff do context 'when the raw diffs are empty' do before do - MergeRequestDiffFile.delete_all(merge_request_diff_id: diff_with_commits.id) + MergeRequestDiffFile.where(merge_request_diff_id: diff_with_commits.id).delete_all end it 'returns an empty DiffCollection' do diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index bf4117fbcaf..4cc3a6a3644 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -559,6 +559,57 @@ describe MergeRequest do end end + describe '#preload_discussions_diff_highlight' do + let(:merge_request) { create(:merge_request) } + + context 'with commit diff note' do + let(:other_merge_request) { create(:merge_request) } + + let!(:diff_note) do + create(:diff_note_on_commit, project: merge_request.project) + end + + let!(:other_mr_diff_note) do + create(:diff_note_on_commit, project: other_merge_request.project) + end + + it 'preloads diff highlighting' do + expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection| + note_diff_file = diff_note.note_diff_file + + expect(collection) + .to receive(:load_highlight) + .with([note_diff_file.id]).and_call_original + end + + merge_request.preload_discussions_diff_highlight + end + end + + context 'with merge request diff note' do + let!(:unresolved_diff_note) do + create(:diff_note_on_merge_request, project: merge_request.project, noteable: merge_request) + end + + let!(:resolved_diff_note) do + create(:diff_note_on_merge_request, :resolved, project: merge_request.project, noteable: merge_request) + end + + it 'preloads diff highlighting' do + expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection| + note_diff_file = unresolved_diff_note.note_diff_file + + expect(collection) + .to receive(:load_highlight) + .with([note_diff_file.id]) + .and_call_original + end + + merge_request.preload_discussions_diff_highlight + end + end + end + describe '#diff_size' do let(:merge_request) do build(:merge_request, source_branch: 'expand-collapse-files', target_branch: 'master') @@ -1358,7 +1409,7 @@ describe MergeRequest do it 'does not raises a NameError exception' do allow_any_instance_of(service_class_name.constantize).to receive(:execute).and_return(nil) - expect { subject }.not_to raise_error(NameError) + expect { subject }.not_to raise_error end end end @@ -2092,7 +2143,7 @@ describe MergeRequest do head_commit_sha: commit.sha ) - subject.merge_request_diff(true) + subject.reload_merge_request_diff end end diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb index d11eb46159e..b3d31e65c85 100644 --- a/spec/models/milestone_spec.rb +++ b/spec/models/milestone_spec.rb @@ -316,6 +316,15 @@ describe Milestone do end end + describe '#reference_link_text' do + let(:project) { build_stubbed(:project, name: 'sample-project') } + let(:milestone) { build_stubbed(:milestone, iid: 1, project: project, name: 'milestone') } + + it 'returns the title with the reference prefix' do + expect(milestone.reference_link_text).to eq '%milestone' + end + end + describe '#participants' do let(:project) { build(:project, name: 'sample-project') } let(:milestone) { build(:milestone, iid: 1, project: project) } diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 18b54cce834..475fbe56e4d 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -337,32 +337,40 @@ describe Namespace do end end - it 'updates project full path in .git/config for each project inside namespace' do - parent = create(:group, name: 'mygroup', path: 'mygroup') - subgroup = create(:group, name: 'mysubgroup', path: 'mysubgroup', parent: parent) - project_in_parent_group = create(:project, :legacy_storage, :repository, namespace: parent, name: 'foo1') - hashed_project_in_subgroup = create(:project, :repository, namespace: subgroup, name: 'foo2') - legacy_project_in_subgroup = create(:project, :legacy_storage, :repository, namespace: subgroup, name: 'foo3') - - parent.update(path: 'mygroup_new') - - # Routes are loaded when creating the projects, so we need to manually - # reload them for the below code to be aware of the above UPDATE. - [ - project_in_parent_group, - hashed_project_in_subgroup, - legacy_project_in_subgroup - ].each do |project| - project.route.reload + context 'for each project inside the namespace' do + let!(:parent) { create(:group, name: 'mygroup', path: 'mygroup') } + let!(:subgroup) { create(:group, name: 'mysubgroup', path: 'mysubgroup', parent: parent) } + let!(:project_in_parent_group) { create(:project, :legacy_storage, :repository, namespace: parent, name: 'foo1') } + let!(:hashed_project_in_subgroup) { create(:project, :repository, namespace: subgroup, name: 'foo2') } + let!(:legacy_project_in_subgroup) { create(:project, :legacy_storage, :repository, namespace: subgroup, name: 'foo3') } + + it 'updates project full path in .git/config' do + parent.update(path: 'mygroup_new') + + expect(project_rugged(project_in_parent_group).config['gitlab.fullpath']).to eq "mygroup_new/#{project_in_parent_group.path}" + expect(project_rugged(hashed_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{hashed_project_in_subgroup.path}" + expect(project_rugged(legacy_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{legacy_project_in_subgroup.path}" end - expect(project_rugged(project_in_parent_group).config['gitlab.fullpath']).to eq "mygroup_new/#{project_in_parent_group.path}" - expect(project_rugged(hashed_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{hashed_project_in_subgroup.path}" - expect(project_rugged(legacy_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{legacy_project_in_subgroup.path}" - end + it 'updates the project storage location' do + repository_project_in_parent_group = create(:project_repository, project: project_in_parent_group) + repository_hashed_project_in_subgroup = create(:project_repository, project: hashed_project_in_subgroup) + repository_legacy_project_in_subgroup = create(:project_repository, project: legacy_project_in_subgroup) + + parent.update(path: 'mygroup_moved') + + expect(repository_project_in_parent_group.reload.disk_path).to eq "mygroup_moved/#{project_in_parent_group.path}" + expect(repository_hashed_project_in_subgroup.reload.disk_path).to eq hashed_project_in_subgroup.disk_path + expect(repository_legacy_project_in_subgroup.reload.disk_path).to eq "mygroup_moved/mysubgroup/#{legacy_project_in_subgroup.path}" + end + + def project_rugged(project) + # Routes are loaded when creating the projects, so we need to manually + # reload them for the below code to be aware of the above UPDATE. + project.route.reload - def project_rugged(project) - rugged_repo(project.repository) + rugged_repo(project.repository) + end end end diff --git a/spec/models/notification_setting_spec.rb b/spec/models/notification_setting_spec.rb index 771d834c4bc..c8ab564e3bc 100644 --- a/spec/models/notification_setting_spec.rb +++ b/spec/models/notification_setting_spec.rb @@ -42,12 +42,7 @@ RSpec.describe NotificationSetting do expect(notification_setting.new_issue).to eq(true) expect(notification_setting.close_issue).to eq(true) expect(notification_setting.merge_merge_request).to eq(true) - - # In Rails 5 assigning a value which is not explicitly `true` or `false` ("nil" in this case) - # to a boolean column transforms it to `true`. - # In Rails 4 it transforms the value to `false` with deprecation warning. - # Replace `eq(Gitlab.rails5?)` with `eq(true)` when removing rails5? code. - expect(notification_setting.close_merge_request).to eq(Gitlab.rails5?) + expect(notification_setting.close_merge_request).to eq(true) expect(notification_setting.reopen_merge_request).to eq(false) end end diff --git a/spec/models/pool_repository_spec.rb b/spec/models/pool_repository_spec.rb index 3d3878b8c39..112d4ab56fc 100644 --- a/spec/models/pool_repository_spec.rb +++ b/spec/models/pool_repository_spec.rb @@ -23,4 +23,25 @@ describe PoolRepository do expect(pool.disk_path).to match(%r{\A@pools/\h{2}/\h{2}/\h{64}}) end end + + describe '#unlink_repository' do + let(:pool) { create(:pool_repository, :ready) } + + context 'when the last member leaves' do + it 'schedules pool removal' do + expect(::ObjectPool::DestroyWorker).to receive(:perform_async).with(pool.id).and_call_original + + pool.unlink_repository(pool.source_project.repository) + end + end + + context 'when the second member leaves' do + it 'does not schedule pool removal' do + create(:project, :repository, pool_repository: pool) + expect(::ObjectPool::DestroyWorker).not_to receive(:perform_async).with(pool.id) + + pool.unlink_repository(pool.source_project.repository) + end + end + end end diff --git a/spec/models/project_import_data_spec.rb b/spec/models/project_import_data_spec.rb new file mode 100644 index 00000000000..e9910c0a5d1 --- /dev/null +++ b/spec/models/project_import_data_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ProjectImportData do + describe '#merge_data' do + it 'writes the Hash to the attribute if it is nil' do + row = described_class.new + + row.merge_data('number' => 10) + + expect(row.data).to eq({ 'number' => 10 }) + end + + it 'merges the Hash into an existing Hash if one was present' do + row = described_class.new(data: { 'number' => 10 }) + + row.merge_data('foo' => 'bar') + + expect(row.data).to eq({ 'number' => 10, 'foo' => 'bar' }) + end + end + + describe '#merge_credentials' do + it 'writes the Hash to the attribute if it is nil' do + row = described_class.new + + row.merge_credentials('number' => 10) + + expect(row.credentials).to eq({ 'number' => 10 }) + end + + it 'merges the Hash into an existing Hash if one was present' do + row = described_class.new + + row.credentials = { 'number' => 10 } + row.merge_credentials('foo' => 'bar') + + expect(row.credentials).to eq({ 'number' => 10, 'foo' => 'bar' }) + end + end +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 9e5b06b745a..4b86c6a1836 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -145,25 +145,10 @@ describe Project do end describe 'ci_pipelines association' do - context 'when feature flag pipeline_ci_sources_only is enabled' do - it 'returns only pipelines from ci_sources' do - stub_feature_flags(pipeline_ci_sources_only: true) + it 'returns only pipelines from ci_sources' do + expect(Ci::Pipeline).to receive(:ci_sources).and_call_original - expect(Ci::Pipeline).to receive(:ci_sources).and_call_original - - subject.ci_pipelines - end - end - - context 'when feature flag pipeline_ci_sources_only is disabled' do - it 'returns all pipelines' do - stub_feature_flags(pipeline_ci_sources_only: false) - - expect(Ci::Pipeline).not_to receive(:ci_sources).and_call_original - expect(Ci::Pipeline).to receive(:all).and_call_original.at_least(:once) - - subject.ci_pipelines - end + subject.ci_pipelines end end end @@ -314,6 +299,13 @@ describe Project do expect(project.errors[:import_url].first).to include('Requests to localhost are not allowed') end + it 'does not allow import_url pointing to the local network' do + project = build(:project, import_url: 'https://192.168.1.1') + + expect(project).to be_invalid + expect(project.errors[:import_url].first).to include('Requests to the local network are not allowed') + end + it "does not allow import_url with invalid ports for new projects" do project = build(:project, import_url: 'http://github.com:25/t.git') @@ -1666,26 +1658,54 @@ describe Project do end describe '#track_project_repository' do - let(:project) { create(:project, :repository) } + shared_examples 'tracks storage location' do + context 'when a project repository entry does not exist' do + it 'creates a new entry' do + expect { project.track_project_repository }.to change(project, :project_repository) + end + + it 'tracks the project storage location' do + project.track_project_repository + + expect(project.project_repository).to have_attributes( + disk_path: project.disk_path, + shard_name: project.repository_storage + ) + end + end + + context 'when a tracking entry exists' do + let!(:project_repository) { create(:project_repository, project: project) } + let!(:shard) { create(:shard, name: 'foo') } + + it 'does not create a new entry in the database' do + expect { project.track_project_repository }.not_to change(project, :project_repository) + end - it 'creates a project_repository' do - project.track_project_repository + it 'updates the project storage location' do + allow(project).to receive(:disk_path).and_return('fancy/new/path') + allow(project).to receive(:repository_storage).and_return('foo') - expect(project.reload.project_repository).to be_present - expect(project.project_repository.disk_path).to eq(project.disk_path) - expect(project.project_repository.shard_name).to eq(project.repository_storage) + project.track_project_repository + + expect(project.project_repository).to have_attributes( + disk_path: 'fancy/new/path', + shard_name: 'foo' + ) + end + end end - it 'updates the project_repository' do - project.track_project_repository + context 'with projects on legacy storage' do + let(:project) { create(:project, :repository, :legacy_storage) } - allow(project).to receive(:disk_path).and_return('@fancy/new/path') + it_behaves_like 'tracks storage location' + end - expect do - project.track_project_repository - end.not_to change(ProjectRepository, :count) + context 'with projects on hashed storage' do + let(:project) { create(:project, :repository) } - expect(project.reload.project_repository.disk_path).to eq(project.disk_path) + it_behaves_like 'tracks storage location' end end @@ -3690,7 +3710,7 @@ describe Project do expect(project.badges.count).to eq 3 end - if Group.supports_nested_groups? + if Group.supports_nested_objects? context 'with nested_groups' do let(:parent_group) { create(:group) } @@ -4102,6 +4122,29 @@ describe Project do end end + describe '#object_pool_params' do + let(:project) { create(:project, :repository, :public) } + + subject { project.object_pool_params } + + before do + stub_application_setting(hashed_storage_enabled: true) + end + + context 'when the objects cannot be pooled' do + let(:project) { create(:project, :repository, :private) } + + it { is_expected.to be_empty } + end + + context 'when a pool is created' do + it 'returns that pool repository' do + expect(subject).not_to be_empty + expect(subject[:pool_repository]).to be_persisted + end + end + end + describe '#git_objects_poolable?' do subject { project } diff --git a/spec/models/prometheus_metric_spec.rb b/spec/models/prometheus_metric_spec.rb index 3692fe9a559..2b978c1c8ff 100644 --- a/spec/models/prometheus_metric_spec.rb +++ b/spec/models/prometheus_metric_spec.rb @@ -59,11 +59,65 @@ describe PrometheusMetric do end end + it_behaves_like 'group_title', :nginx_ingress_vts, 'Response metrics (NGINX Ingress VTS)' + it_behaves_like 'group_title', :nginx_ingress, 'Response metrics (NGINX Ingress)' + it_behaves_like 'group_title', :ha_proxy, 'Response metrics (HA Proxy)' + it_behaves_like 'group_title', :aws_elb, 'Response metrics (AWS ELB)' + it_behaves_like 'group_title', :nginx, 'Response metrics (NGINX)' + it_behaves_like 'group_title', :kubernetes, 'System metrics (Kubernetes)' it_behaves_like 'group_title', :business, 'Business metrics (Custom)' it_behaves_like 'group_title', :response, 'Response metrics (Custom)' it_behaves_like 'group_title', :system, 'System metrics (Custom)' end + describe '#priority' do + using RSpec::Parameterized::TableSyntax + + where(:group, :priority) do + :nginx_ingress_vts | 10 + :nginx_ingress | 10 + :ha_proxy | 10 + :aws_elb | 10 + :nginx | 10 + :kubernetes | 5 + :business | 0 + :response | -5 + :system | -10 + end + + with_them do + before do + subject.group = group + end + + it { expect(subject.priority).to eq(priority) } + end + end + + describe '#required_metrics' do + using RSpec::Parameterized::TableSyntax + + where(:group, :required_metrics) do + :nginx_ingress_vts | %w(nginx_upstream_responses_total nginx_upstream_response_msecs_avg) + :nginx_ingress | %w(nginx_ingress_controller_requests nginx_ingress_controller_ingress_upstream_latency_seconds_sum) + :ha_proxy | %w(haproxy_frontend_http_requests_total haproxy_frontend_http_responses_total) + :aws_elb | %w(aws_elb_request_count_sum aws_elb_latency_average aws_elb_httpcode_backend_5_xx_sum) + :nginx | %w(nginx_server_requests nginx_server_requestMsec) + :kubernetes | %w(container_memory_usage_bytes container_cpu_usage_seconds_total) + :business | %w() + :response | %w() + :system | %w() + end + + with_them do + before do + subject.group = group + end + + it { expect(subject.required_metrics).to eq(required_metrics) } + end + end + describe '#to_query_metric' do it 'converts to queryable metric object' do expect(subject.to_query_metric).to be_instance_of(Gitlab::Prometheus::Metric) diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb index 3f86347c3ae..92ba2d82f58 100644 --- a/spec/models/release_spec.rb +++ b/spec/models/release_spec.rb @@ -1,12 +1,15 @@ require 'rails_helper' RSpec.describe Release do - let(:release) { create(:release) } + let(:user) { create(:user) } + let(:project) { create(:project, :public, :repository) } + let(:release) { create(:release, project: project, author: user) } it { expect(release).to be_valid } describe 'associations' do it { is_expected.to belong_to(:project) } + it { is_expected.to belong_to(:author).class_name('User') } end describe 'validation' do diff --git a/spec/models/remote_mirror_spec.rb b/spec/models/remote_mirror_spec.rb index b12ca79847c..224bc9ed935 100644 --- a/spec/models/remote_mirror_spec.rb +++ b/spec/models/remote_mirror_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe RemoteMirror do +describe RemoteMirror, :mailer do include GitHelpers describe 'URL validation' do @@ -24,6 +24,20 @@ describe RemoteMirror do expect(remote_mirror).to be_invalid expect(remote_mirror.errors[:url].first).to include('Username needs to start with an alphanumeric character') end + + it 'does not allow url pointing to localhost' do + remote_mirror = build(:remote_mirror, url: 'http://127.0.0.2/t.git') + + expect(remote_mirror).to be_invalid + expect(remote_mirror.errors[:url].first).to include('Requests to loopback addresses are not allowed') + end + + it 'does not allow url pointing to the local network' do + remote_mirror = build(:remote_mirror, url: 'https://192.168.1.1') + + expect(remote_mirror).to be_invalid + expect(remote_mirror.errors[:url].first).to include('Requests to the local network are not allowed') + end end end @@ -137,6 +151,43 @@ describe RemoteMirror do end end + describe '#mark_as_failed' do + let(:remote_mirror) { create(:remote_mirror) } + let(:error_message) { 'http://user:pass@test.com/root/repoC.git/' } + let(:sanitized_error_message) { 'http://*****:*****@test.com/root/repoC.git/' } + + subject do + remote_mirror.update_start + remote_mirror.mark_as_failed(error_message) + end + + it 'sets the update_status to failed' do + subject + + expect(remote_mirror.reload.update_status).to eq('failed') + end + + it 'saves the sanitized error' do + subject + + expect(remote_mirror.last_error).to eq(sanitized_error_message) + end + + context 'notifications' do + let(:user) { create(:user) } + + before do + remote_mirror.project.add_maintainer(user) + end + + it 'notifies the project maintainers' do + perform_enqueued_jobs { subject } + + should_email(user) + end + end + end + context 'when remote mirror gets destroyed' do it 'removes remote' do mirror = create_mirror(url: 'http://foo:bar@test.com') diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index 7a7272ccb60..664dc3fa145 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -423,4 +423,41 @@ describe Snippet do expect(blob.data).to eq(snippet.content) end end + + describe '#embeddable?' do + context 'project snippet' do + [ + { project: :public, snippet: :public, embeddable: true }, + { project: :internal, snippet: :public, embeddable: false }, + { project: :private, snippet: :public, embeddable: false }, + { project: :public, snippet: :internal, embeddable: false }, + { project: :internal, snippet: :internal, embeddable: false }, + { project: :private, snippet: :internal, embeddable: false }, + { project: :public, snippet: :private, embeddable: false }, + { project: :internal, snippet: :private, embeddable: false }, + { project: :private, snippet: :private, embeddable: false } + ].each do |combination| + it 'only returns true when both project and snippet are public' do + project = create(:project, combination[:project]) + snippet = create(:project_snippet, combination[:snippet], project: project) + + expect(snippet.embeddable?).to eq(combination[:embeddable]) + end + end + end + + context 'personal snippet' do + [ + { snippet: :public, embeddable: true }, + { snippet: :internal, embeddable: false }, + { snippet: :private, embeddable: false } + ].each do |combination| + it 'only returns true when snippet is public' do + snippet = create(:personal_snippet, combination[:snippet]) + + expect(snippet.embeddable?).to eq(combination[:embeddable]) + end + end + end + end end diff --git a/spec/models/suggestion_spec.rb b/spec/models/suggestion_spec.rb new file mode 100644 index 00000000000..cafc725dddb --- /dev/null +++ b/spec/models/suggestion_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Suggestion do + let(:suggestion) { create(:suggestion) } + + describe 'associations' do + it { is_expected.to belong_to(:note) } + end + + describe 'validations' do + it { is_expected.to validate_presence_of(:note) } + + context 'when suggestion is applied' do + before do + allow(subject).to receive(:applied?).and_return(true) + end + + it { is_expected.to validate_presence_of(:commit_id) } + end + end + + describe '#appliable?' do + context 'when note does not support suggestions' do + it 'returns false' do + expect_next_instance_of(DiffNote) do |note| + allow(note).to receive(:supports_suggestion?) { false } + end + + expect(suggestion).not_to be_appliable + end + end + + context 'when patch is already applied' do + let(:suggestion) { create(:suggestion, :applied) } + + it 'returns false' do + expect(suggestion).not_to be_appliable + end + end + + context 'when merge request is not opened' do + let(:merge_request) { create(:merge_request, :merged) } + let(:note) do + create(:diff_note_on_merge_request, project: merge_request.project, + noteable: merge_request) + end + + let(:suggestion) { create(:suggestion, note: note) } + + it 'returns false' do + expect(suggestion).not_to be_appliable + end + end + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ff075e65c76..33842e74b92 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -45,6 +45,7 @@ describe User do it { is_expected.to have_many(:uploads) } it { is_expected.to have_many(:reported_abuse_reports).dependent(:destroy).class_name('AbuseReport') } it { is_expected.to have_many(:custom_attributes).class_name('UserCustomAttribute') } + it { is_expected.to have_many(:releases).dependent(:nullify) } describe "#abuse_report" do let(:current_user) { create(:user) } @@ -1965,7 +1966,7 @@ describe User do subject { user.membership_groups } - if Group.supports_nested_groups? + if Group.supports_nested_objects? it { is_expected.to contain_exactly parent_group, child_group } else it { is_expected.to contain_exactly parent_group } @@ -2346,7 +2347,7 @@ describe User do group.add_owner(user) end - if Group.supports_nested_groups? + if Group.supports_nested_objects? it 'returns all groups' do is_expected.to match_array [ group, diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 9d0093e8159..be1804c5ce0 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -25,7 +25,8 @@ describe GroupPolicy do :read_cluster, :create_cluster, :update_cluster, - :admin_cluster + :admin_cluster, + :add_cluster ] end @@ -147,7 +148,7 @@ describe GroupPolicy do let(:current_user) { owner } it do - allow(Group).to receive(:supports_nested_groups?).and_return(true) + allow(Group).to receive(:supports_nested_objects?).and_return(true) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) @@ -161,7 +162,7 @@ describe GroupPolicy do let(:current_user) { admin } it do - allow(Group).to receive(:supports_nested_groups?).and_return(true) + allow(Group).to receive(:supports_nested_objects?).and_return(true) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) @@ -173,7 +174,7 @@ describe GroupPolicy do describe 'when nested group support feature is disabled' do before do - allow(Group).to receive(:supports_nested_groups?).and_return(false) + allow(Group).to receive(:supports_nested_objects?).and_return(false) end context 'admin' do @@ -282,7 +283,7 @@ describe GroupPolicy do let(:current_user) { owner } it do - allow(Group).to receive(:supports_nested_groups?).and_return(true) + allow(Group).to receive(:supports_nested_objects?).and_return(true) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) @@ -382,4 +383,14 @@ describe GroupPolicy do it { expect_disallowed(:change_share_with_group_lock) } end end + + it_behaves_like 'clusterable policies' do + let(:clusterable) { create(:group) } + let(:cluster) do + create(:cluster, + :provided_by_gcp, + :group, + groups: [clusterable]) + end + end end diff --git a/spec/policies/issuable_policy_spec.rb b/spec/policies/issuable_policy_spec.rb index d1bf98995e7..db3df760472 100644 --- a/spec/policies/issuable_policy_spec.rb +++ b/spec/policies/issuable_policy_spec.rb @@ -7,6 +7,33 @@ describe IssuablePolicy, models: true do let(:policies) { described_class.new(user, issue) } describe '#rules' do + context 'when user is author of issuable' do + let(:merge_request) { create(:merge_request, source_project: project, author: user) } + let(:policies) { described_class.new(user, merge_request) } + + context 'when user is able to read project' do + it 'enables user to read and update issuables' do + expect(policies).to be_allowed(:read_issue, :update_issue, :reopen_issue, :read_merge_request, :update_merge_request) + end + end + + context 'when project is private' do + let(:project) { create(:project, :private) } + + context 'when user belongs to the projects team' do + it 'enables user to read and update issuables' do + project.add_maintainer(user) + + expect(policies).to be_allowed(:read_issue, :update_issue, :reopen_issue, :read_merge_request, :update_merge_request) + end + end + + it 'disallows user from reading and updating issuables from that project' do + expect(policies).to be_disallowed(:read_issue, :update_issue, :reopen_issue, :read_merge_request, :update_merge_request) + end + end + end + context 'when discussion is locked for the issuable' do let(:issue) { create(:issue, project: project, discussion_locked: true) } diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index 69468f9ad85..9cb20854f6e 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -15,7 +15,7 @@ describe ProjectPolicy do read_project_for_iids read_issue_iid read_merge_request_iid read_label read_milestone read_project_snippet read_project_member read_note create_project create_issue create_note upload_file create_merge_request_in - award_emoji + award_emoji read_release ] end @@ -38,7 +38,7 @@ describe ProjectPolicy do update_commit_status create_build update_build create_pipeline update_pipeline create_merge_request_from create_wiki push_code resolve_note create_container_image update_container_image - create_environment create_deployment + create_environment create_deployment create_release update_release ] end @@ -48,7 +48,7 @@ describe ProjectPolicy do update_deployment admin_project_snippet admin_project_member admin_note admin_wiki admin_project admin_commit_status admin_build admin_container_image - admin_pipeline admin_environment admin_deployment + admin_pipeline admin_environment admin_deployment destroy_release add_cluster ] end @@ -56,7 +56,7 @@ describe ProjectPolicy do %i[ download_code fork_project read_commit_status read_pipeline read_container_image build_download_code build_read_container_image - download_wiki_code + download_wiki_code read_release ] end @@ -183,7 +183,8 @@ describe ProjectPolicy do :create_pipeline_schedule, :read_pipeline_schedule, :update_pipeline_schedule, :admin_pipeline_schedule, :destroy_pipeline_schedule, :create_environment, :read_environment, :update_environment, :admin_environment, :destroy_environment, :create_cluster, :read_cluster, :update_cluster, :admin_cluster, - :create_deployment, :read_deployment, :update_deployment, :admin_deployment, :destroy_deployment + :create_deployment, :read_deployment, :update_deployment, :admin_deployment, :destroy_deployment, + :destroy_release ] expect_disallowed(*repository_permissions) @@ -465,4 +466,14 @@ describe ProjectPolicy do expect_disallowed(*maintainer_abilities) end end + + it_behaves_like 'clusterable policies' do + let(:clusterable) { create(:project, :repository) } + let(:cluster) do + create(:cluster, + :provided_by_gcp, + :project, + projects: [clusterable]) + end + end end diff --git a/spec/presenters/clusterable_presenter_spec.rb b/spec/presenters/clusterable_presenter_spec.rb index 4f4ae5e07c5..05afe5347d1 100644 --- a/spec/presenters/clusterable_presenter_spec.rb +++ b/spec/presenters/clusterable_presenter_spec.rb @@ -14,4 +14,68 @@ describe ClusterablePresenter do expect(subject).to be_kind_of(ProjectClusterablePresenter) end end + + shared_examples 'appropriate member permissions' do + context 'with a developer' do + before do + clusterable.add_developer(user) + end + + it { is_expected.to be_falsy } + end + + context 'with a maintainer' do + before do + clusterable.add_maintainer(user) + end + + it { is_expected.to be_truthy } + end + end + + describe '#can_create_cluster?' do + let(:user) { create(:user) } + + subject { described_class.new(clusterable).can_create_cluster? } + + before do + allow(clusterable).to receive(:current_user).and_return(user) + end + + context 'when clusterable is a group' do + let(:clusterable) { create(:group) } + + it_behaves_like 'appropriate member permissions' + end + + context 'when clusterable is a project' do + let(:clusterable) { create(:project, :repository) } + + it_behaves_like 'appropriate member permissions' + end + end + + describe '#can_add_cluster?' do + let(:user) { create(:user) } + + subject { described_class.new(clusterable).can_add_cluster? } + + before do + clusterable.add_maintainer(user) + + allow(clusterable).to receive(:current_user).and_return(user) + end + + context 'when clusterable is a group' do + let(:clusterable) { create(:group) } + + it_behaves_like 'appropriate member permissions' + end + + context 'when clusterable is a project' do + let(:clusterable) { create(:project, :repository) } + + it_behaves_like 'appropriate member permissions' + end + end end diff --git a/spec/presenters/clusters/cluster_presenter_spec.rb b/spec/presenters/clusters/cluster_presenter_spec.rb index 72c5eac3ede..754ba0a594c 100644 --- a/spec/presenters/clusters/cluster_presenter_spec.rb +++ b/spec/presenters/clusters/cluster_presenter_spec.rb @@ -4,9 +4,10 @@ describe Clusters::ClusterPresenter do include Gitlab::Routing.url_helpers let(:cluster) { create(:cluster, :provided_by_gcp, :project) } + let(:user) { create(:user) } subject(:presenter) do - described_class.new(cluster) + described_class.new(cluster, current_user: user) end it 'inherits from Gitlab::View::Presenter::Delegated' do @@ -27,6 +28,129 @@ describe Clusters::ClusterPresenter do end end + describe '#item_link' do + let(:clusterable_presenter) { double('ClusterablePresenter', subject: clusterable) } + + subject { presenter.item_link(clusterable_presenter) } + + context 'for a group cluster' do + let(:cluster) { create(:cluster, cluster_type: :group_type, groups: [group]) } + let(:group) { create(:group, name: 'Foo') } + let(:cluster_link) { "<a href=\"#{group_cluster_path(cluster.group, cluster)}\">#{cluster.name}</a>" } + + before do + group.add_maintainer(user) + end + + shared_examples 'ancestor clusters' do + context 'ancestor clusters', :nested_groups do + let(:root_group) { create(:group, name: 'Root Group') } + let(:parent) { create(:group, name: 'parent', parent: root_group) } + let(:child) { create(:group, name: 'child', parent: parent) } + let(:group) { create(:group, name: 'group', parent: child) } + + before do + root_group.add_maintainer(user) + end + + context 'top level group cluster' do + let(:cluster) { create(:cluster, cluster_type: :group_type, groups: [root_group]) } + + it 'returns full group names and link for cluster' do + expect(subject).to eq("Root Group / #{cluster_link}") + end + + it 'is html safe' do + expect(presenter).to receive(:sanitize).with('Root Group').and_call_original + + expect(subject).to be_html_safe + end + end + + context 'first level group cluster' do + let(:cluster) { create(:cluster, cluster_type: :group_type, groups: [parent]) } + + it 'returns full group names and link for cluster' do + expect(subject).to eq("Root Group / parent / #{cluster_link}") + end + + it 'is html safe' do + expect(presenter).to receive(:sanitize).with('Root Group / parent').and_call_original + + expect(subject).to be_html_safe + end + end + + context 'second level group cluster' do + let(:cluster) { create(:cluster, cluster_type: :group_type, groups: [child]) } + + let(:ellipsis_h) do + /.*ellipsis_h.*/ + end + + it 'returns clipped group names and link for cluster' do + expect(subject).to match("Root Group / #{ellipsis_h} / child / #{cluster_link}") + end + + it 'is html safe' do + expect(presenter).to receive(:sanitize).with('Root Group / parent / child').and_call_original + + expect(subject).to be_html_safe + end + end + end + end + + context 'for a project clusterable' do + let(:clusterable) { project } + let(:project) { create(:project, group: group) } + + it 'returns the group name and the link for cluster' do + expect(subject).to eq("Foo / #{cluster_link}") + end + + it 'is html safe' do + expect(presenter).to receive(:sanitize).with('Foo').and_call_original + + expect(subject).to be_html_safe + end + + include_examples 'ancestor clusters' + end + + context 'for the group clusterable for the cluster' do + let(:clusterable) { group } + + it 'returns link for cluster' do + expect(subject).to eq(cluster_link) + end + + include_examples 'ancestor clusters' + + it 'is html safe' do + expect(subject).to be_html_safe + end + end + end + + context 'for a project cluster' do + let(:cluster) { create(:cluster, :project) } + let(:cluster_link) { "<a href=\"#{project_cluster_path(cluster.project, cluster)}\">#{cluster.name}</a>" } + + before do + cluster.project.add_maintainer(user) + end + + context 'for the project clusterable' do + let(:clusterable) { cluster.project } + + it 'returns link for cluster' do + expect(subject).to eq(cluster_link) + end + end + end + end + describe '#gke_cluster_url' do subject { described_class.new(cluster).gke_cluster_url } @@ -74,6 +198,20 @@ describe Clusters::ClusterPresenter do end end + describe '#cluster_type_description' do + subject { described_class.new(cluster).cluster_type_description } + + context 'project_type cluster' do + it { is_expected.to eq('Project cluster') } + end + + context 'group_type cluster' do + let(:cluster) { create(:cluster, :provided_by_gcp, :group) } + + it { is_expected.to eq('Group cluster') } + end + end + describe '#show_path' do subject { described_class.new(cluster).show_path } diff --git a/spec/requests/api/access_requests_spec.rb b/spec/requests/api/access_requests_spec.rb index e13129967b2..1af6602ea9e 100644 --- a/spec/requests/api/access_requests_spec.rb +++ b/spec/requests/api/access_requests_spec.rb @@ -145,7 +145,7 @@ describe API::AccessRequests do it 'returns 201' do expect do put api("/#{source_type.pluralize}/#{source.id}/access_requests/#{access_requester.id}/approve", maintainer), - access_level: Member::MAINTAINER + params: { access_level: Member::MAINTAINER } expect(response).to have_gitlab_http_status(201) end.to change { source.members.count }.by(1) diff --git a/spec/requests/api/applications_spec.rb b/spec/requests/api/applications_spec.rb index 6154be5c425..e47166544d9 100644 --- a/spec/requests/api/applications_spec.rb +++ b/spec/requests/api/applications_spec.rb @@ -11,7 +11,7 @@ describe API::Applications, :api do context 'authenticated and authorized user' do it 'creates and returns an OAuth application' do expect do - post api('/applications', admin_user), name: 'application_name', redirect_uri: 'http://application.url', scopes: '' + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: '' } end.to change { Doorkeeper::Application.count }.by 1 application = Doorkeeper::Application.find_by(name: 'application_name', redirect_uri: 'http://application.url') @@ -25,7 +25,7 @@ describe API::Applications, :api do it 'does not allow creating an application with the wrong redirect_uri format' do expect do - post api('/applications', admin_user), name: 'application_name', redirect_uri: 'http://', scopes: '' + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://', scopes: '' } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(400) @@ -35,7 +35,7 @@ describe API::Applications, :api do it 'does not allow creating an application with a forbidden URI format' do expect do - post api('/applications', admin_user), name: 'application_name', redirect_uri: 'javascript://alert()', scopes: '' + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'javascript://alert()', scopes: '' } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(400) @@ -45,7 +45,7 @@ describe API::Applications, :api do it 'does not allow creating an application without a name' do expect do - post api('/applications', admin_user), redirect_uri: 'http://application.url', scopes: '' + post api('/applications', admin_user), params: { redirect_uri: 'http://application.url', scopes: '' } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(400) @@ -55,7 +55,7 @@ describe API::Applications, :api do it 'does not allow creating an application without a redirect_uri' do expect do - post api('/applications', admin_user), name: 'application_name', scopes: '' + post api('/applications', admin_user), params: { name: 'application_name', scopes: '' } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(400) @@ -65,7 +65,7 @@ describe API::Applications, :api do it 'does not allow creating an application without scopes' do expect do - post api('/applications', admin_user), name: 'application_name', redirect_uri: 'http://application.url' + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url' } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(400) @@ -77,7 +77,7 @@ describe API::Applications, :api do context 'authorized user without authorization' do it 'does not create application' do expect do - post api('/applications', user), name: 'application_name', redirect_uri: 'http://application.url', scopes: '' + post api('/applications', user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: '' } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(403) @@ -87,7 +87,7 @@ describe API::Applications, :api do context 'non-authenticated user' do it 'does not create application' do expect do - post api('/applications'), name: 'application_name', redirect_uri: 'http://application.url' + post api('/applications'), params: { name: 'application_name', redirect_uri: 'http://application.url' } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(401) diff --git a/spec/requests/api/avatar_spec.rb b/spec/requests/api/avatar_spec.rb index 26e0435a6d5..17e66725dc9 100644 --- a/spec/requests/api/avatar_spec.rb +++ b/spec/requests/api/avatar_spec.rb @@ -13,7 +13,7 @@ describe API::Avatar do end it 'returns the avatar url' do - get api('/avatar'), { email: 'public@example.com' } + get api('/avatar'), params: { email: 'public@example.com' } expect(response.status).to eq 200 expect(json_response['avatar_url']).to eql("#{::Settings.gitlab.base_url}#{user.avatar.local_url}") @@ -30,7 +30,7 @@ describe API::Avatar do end it 'returns the avatar url from Gravatar' do - get api('/avatar'), { email: 'private@example.com' } + get api('/avatar'), params: { email: 'private@example.com' } expect(response.status).to eq 200 expect(json_response['avatar_url']).to eq('https://gravatar') @@ -53,7 +53,7 @@ describe API::Avatar do end it 'returns the avatar url from Gravatar' do - get api('/avatar'), { email: 'public@example.com' } + get api('/avatar'), params: { email: 'public@example.com' } expect(response.status).to eq 200 expect(json_response['avatar_url']).to eq('https://gravatar') @@ -70,7 +70,7 @@ describe API::Avatar do end it 'returns the avatar url from Gravatar' do - get api('/avatar'), { email: 'private@example.com' } + get api('/avatar'), params: { email: 'private@example.com' } expect(response.status).to eq 200 expect(json_response['avatar_url']).to eq('https://gravatar') @@ -88,7 +88,7 @@ describe API::Avatar do context 'when authenticated' do it 'returns the avatar url' do - get api('/avatar', user), { email: 'public@example.com' } + get api('/avatar', user), params: { email: 'public@example.com' } expect(response.status).to eq 200 expect(json_response['avatar_url']).to eql("#{::Settings.gitlab.base_url}#{user.avatar.local_url}") @@ -97,7 +97,7 @@ describe API::Avatar do context 'when unauthenticated' do it_behaves_like '403 response' do - let(:request) { get api('/avatar'), { email: 'public@example.com' } } + let(:request) { get api('/avatar'), params: { email: 'public@example.com' } } end end end diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb index 7f3f3ab0977..22f6fcdc922 100644 --- a/spec/requests/api/award_emoji_spec.rb +++ b/spec/requests/api/award_emoji_spec.rb @@ -148,7 +148,7 @@ describe API::AwardEmoji do context "on an issue" do it "creates a new award emoji" do - post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), name: 'blowfish' + post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), params: { name: 'blowfish' } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq('blowfish') @@ -162,21 +162,21 @@ describe API::AwardEmoji do end it "returns a 401 unauthorized error if the user is not authenticated" do - post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji"), name: 'thumbsup' + post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji"), params: { name: 'thumbsup' } expect(response).to have_gitlab_http_status(401) end it "normalizes +1 as thumbsup award" do - post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), name: '+1' + post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), params: { name: '+1' } expect(issue.award_emoji.last.name).to eq("thumbsup") end context 'when the emoji already has been awarded' do it 'returns a 404 status code' do - post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), name: 'thumbsup' - post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), name: 'thumbsup' + post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), params: { name: 'thumbsup' } + post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), params: { name: 'thumbsup' } expect(response).to have_gitlab_http_status(404) expect(json_response["message"]).to match("has already been taken") @@ -188,7 +188,7 @@ describe API::AwardEmoji do it 'creates a new award emoji' do snippet = create(:project_snippet, :public, project: project) - post api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji", user), name: 'blowfish' + post api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji", user), params: { name: 'blowfish' } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq('blowfish') @@ -202,7 +202,7 @@ describe API::AwardEmoji do it 'creates a new award emoji' do expect do - post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), name: 'rocket' + post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), params: { name: 'rocket' } end.to change { note.award_emoji.count }.from(0).to(1) expect(response).to have_gitlab_http_status(201) @@ -210,15 +210,15 @@ describe API::AwardEmoji do end it "normalizes +1 as thumbsup award" do - post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), name: '+1' + post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), params: { name: '+1' } expect(note.award_emoji.last.name).to eq("thumbsup") end context 'when the emoji already has been awarded' do it 'returns a 404 status code' do - post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), name: 'rocket' - post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), name: 'rocket' + post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), params: { name: 'rocket' } + post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), params: { name: 'rocket' } expect(response).to have_gitlab_http_status(404) expect(json_response["message"]).to match("has already been taken") diff --git a/spec/requests/api/badges_spec.rb b/spec/requests/api/badges_spec.rb index e232e2e04ee..1271324a2ba 100644 --- a/spec/requests/api/badges_spec.rb +++ b/spec/requests/api/badges_spec.rb @@ -103,7 +103,7 @@ describe API::Badges do it_behaves_like 'a 404 response when source is private' do let(:route) do post api("/#{source_type.pluralize}/#{source.id}/badges", stranger), - link_url: example_url, image_url: example_url2 + params: { link_url: example_url, image_url: example_url2 } end end @@ -114,7 +114,7 @@ describe API::Badges do user = public_send(type) post api("/#{source_type.pluralize}/#{source.id}/badges", user), - link_url: example_url, image_url: example_url2 + params: { link_url: example_url, image_url: example_url2 } expect(response).to have_gitlab_http_status(403) end @@ -126,7 +126,7 @@ describe API::Badges do it 'creates a new badge' do expect do post api("/#{source_type.pluralize}/#{source.id}/badges", maintainer), - link_url: example_url, image_url: example_url2 + params: { link_url: example_url, image_url: example_url2 } expect(response).to have_gitlab_http_status(201) end.to change { source.badges.count }.by(1) @@ -139,21 +139,21 @@ describe API::Badges do it 'returns 400 when link_url is not given' do post api("/#{source_type.pluralize}/#{source.id}/badges", maintainer), - link_url: example_url + params: { link_url: example_url } expect(response).to have_gitlab_http_status(400) end it 'returns 400 when image_url is not given' do post api("/#{source_type.pluralize}/#{source.id}/badges", maintainer), - image_url: example_url2 + params: { image_url: example_url2 } expect(response).to have_gitlab_http_status(400) end it 'returns 400 when link_url or image_url is not valid' do post api("/#{source_type.pluralize}/#{source.id}/badges", maintainer), - link_url: 'whatever', image_url: 'whatever' + params: { link_url: 'whatever', image_url: 'whatever' } expect(response).to have_gitlab_http_status(400) end @@ -173,7 +173,7 @@ describe API::Badges do it_behaves_like 'a 404 response when source is private' do let(:route) do put api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", stranger), - link_url: example_url + params: { link_url: example_url } end end @@ -184,7 +184,7 @@ describe API::Badges do user = public_send(type) put api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", user), - link_url: example_url + params: { link_url: example_url } expect(response).to have_gitlab_http_status(403) end @@ -195,7 +195,7 @@ describe API::Badges do context 'when authenticated as a maintainer/owner' do it 'updates the member' do put api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", maintainer), - link_url: example_url, image_url: example_url2 + params: { link_url: example_url, image_url: example_url2 } expect(response).to have_gitlab_http_status(200) expect(json_response['link_url']).to eq(example_url) @@ -206,7 +206,7 @@ describe API::Badges do it 'returns 400 when link_url or image_url is not valid' do put api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", maintainer), - link_url: 'whatever', image_url: 'whatever' + params: { link_url: 'whatever', image_url: 'whatever' } expect(response).to have_gitlab_http_status(400) end diff --git a/spec/requests/api/boards_spec.rb b/spec/requests/api/boards_spec.rb index 7710f19ce4e..ab4f42cad47 100644 --- a/spec/requests/api/boards_spec.rb +++ b/spec/requests/api/boards_spec.rb @@ -41,7 +41,7 @@ describe API::Boards do group_label = create(:group_label, group: group) board_parent.update(group: group) - post api(url, user), label_id: group_label.id + post api(url, user), params: { label_id: group_label.id } expect(response).to have_gitlab_http_status(201) expect(json_response['label']['name']).to eq(group_label.title) @@ -56,7 +56,7 @@ describe API::Boards do group.add_developer(user) sub_group.add_developer(user) - post api(url, user), label_id: group_label.id + post api(url, user), params: { label_id: group_label.id } expect(response).to have_gitlab_http_status(201) expect(json_response['label']['name']).to eq(group_label.title) @@ -73,7 +73,7 @@ describe API::Boards do group.add_developer(user) group_label = create(:group_label, group: group) - post api(url, user), label_id: group_label.id + post api(url, user), params: { label_id: group_label.id } expect(response).to have_gitlab_http_status(201) expect(json_response['label']['name']).to eq(group_label.title) diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb index 7fff0a6cce6..b38cd66986f 100644 --- a/spec/requests/api/branches_spec.rb +++ b/spec/requests/api/branches_spec.rb @@ -20,8 +20,14 @@ describe API::Branches do let(:route) { "/projects/#{project_id}/repository/branches" } shared_examples_for 'repository branches' do + RSpec::Matchers.define :has_merged_branch_names_count do |expected| + match do |actual| + actual[:merged_branch_names].count == expected + end + end + it 'returns the repository branches' do - get api(route, current_user), per_page: 100 + get api(route, current_user), params: { per_page: 100 } expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('public_api/v4/branches') @@ -30,6 +36,12 @@ describe API::Branches do expect(branch_names).to match_array(project.repository.branch_names) end + it 'determines only a limited number of merged branch names' do + expect(API::Entities::Branch).to receive(:represent).with(anything, has_merged_branch_names_count(2)) + + get api(route, current_user), params: { per_page: 2 } + end + context 'when repository is disabled' do include_context 'disabled repository' @@ -42,7 +54,7 @@ describe API::Branches do context 'when search parameter is passed' do context 'and branch exists' do it 'returns correct branches' do - get api(route, user), per_page: 100, search: branch_name + get api(route, user), params: { per_page: 100, search: branch_name } searched_branch_names = json_response.map { |branch| branch['name'] } project_branch_names = project.repository.branch_names.grep(/#{branch_name}/) @@ -53,7 +65,7 @@ describe API::Branches do context 'and branch does not exist' do it 'returns an empty array' do - get api(route, user), per_page: 100, search: 'no_such_branch_name_entropy_of_jabadabadu' + get api(route, user), params: { per_page: 100, search: 'no_such_branch_name_entropy_of_jabadabadu' } expect(json_response).to eq [] end @@ -252,7 +264,7 @@ describe API::Branches do end it 'protects a single branch and developers can push' do - put api(route, current_user), developers_can_push: true + put api(route, current_user), params: { developers_can_push: true } expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('public_api/v4/branch') @@ -263,7 +275,7 @@ describe API::Branches do end it 'protects a single branch and developers can merge' do - put api(route, current_user), developers_can_merge: true + put api(route, current_user), params: { developers_can_merge: true } expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('public_api/v4/branch') @@ -274,7 +286,7 @@ describe API::Branches do end it 'protects a single branch and developers can push and merge' do - put api(route, current_user), developers_can_push: true, developers_can_merge: true + put api(route, current_user), params: { developers_can_push: true, developers_can_merge: true } expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('public_api/v4/branch') @@ -373,7 +385,7 @@ describe API::Branches do it 'updates that a developer cannot push or merge' do put api("/projects/#{project.id}/repository/branches/#{protected_branch.name}/protect", user), - developers_can_push: false, developers_can_merge: false + params: { developers_can_push: false, developers_can_merge: false } expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('public_api/v4/branch') @@ -391,7 +403,7 @@ describe API::Branches do it 'updates that a developer can push and merge' do put api("/projects/#{project.id}/repository/branches/#{protected_branch.name}/protect", user), - developers_can_push: true, developers_can_merge: true + params: { developers_can_push: true, developers_can_merge: true } expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('public_api/v4/branch') @@ -504,7 +516,7 @@ describe API::Branches do shared_examples_for 'repository new branch' do it 'creates a new branch' do - post api(route, current_user), branch: 'feature1', ref: branch_sha + post api(route, current_user), params: { branch: 'feature1', ref: branch_sha } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/branch') @@ -549,25 +561,25 @@ describe API::Branches do end it 'returns 400 if branch name is invalid' do - post api(route, user), branch: 'new design', ref: branch_sha + post api(route, user), params: { branch: 'new design', ref: branch_sha } expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('Branch name is invalid') end it 'returns 400 if branch already exists' do - post api(route, user), branch: 'new_design1', ref: branch_sha + post api(route, user), params: { branch: 'new_design1', ref: branch_sha } expect(response).to have_gitlab_http_status(201) - post api(route, user), branch: 'new_design1', ref: branch_sha + post api(route, user), params: { branch: 'new_design1', ref: branch_sha } expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('Branch already exists') end it 'returns 400 if ref name is invalid' do - post api(route, user), branch: 'new_design3', ref: 'foo' + post api(route, user), params: { branch: 'new_design3', ref: 'foo' } expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('Invalid reference name') diff --git a/spec/requests/api/broadcast_messages_spec.rb b/spec/requests/api/broadcast_messages_spec.rb index fe8a14fae9e..0b48b79219c 100644 --- a/spec/requests/api/broadcast_messages_spec.rb +++ b/spec/requests/api/broadcast_messages_spec.rb @@ -56,13 +56,13 @@ describe API::BroadcastMessages do describe 'POST /broadcast_messages' do it 'returns a 401 for anonymous users' do - post api('/broadcast_messages'), attributes_for(:broadcast_message) + post api('/broadcast_messages'), params: attributes_for(:broadcast_message) expect(response).to have_gitlab_http_status(401) end it 'returns a 403 for users' do - post api('/broadcast_messages', user), attributes_for(:broadcast_message) + post api('/broadcast_messages', user), params: attributes_for(:broadcast_message) expect(response).to have_gitlab_http_status(403) end @@ -72,7 +72,7 @@ describe API::BroadcastMessages do attrs = attributes_for(:broadcast_message) attrs.delete(:message) - post api('/broadcast_messages', admin), attrs + post api('/broadcast_messages', admin), params: attrs expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq 'message is missing' @@ -81,7 +81,7 @@ describe API::BroadcastMessages do it 'defines sane default start and end times' do time = Time.zone.parse('2016-07-02 10:11:12') travel_to(time) do - post api('/broadcast_messages', admin), message: 'Test message' + post api('/broadcast_messages', admin), params: { message: 'Test message' } expect(response).to have_gitlab_http_status(201) expect(json_response['starts_at']).to eq '2016-07-02T10:11:12.000Z' @@ -92,7 +92,7 @@ describe API::BroadcastMessages do it 'accepts a custom background and foreground color' do attrs = attributes_for(:broadcast_message, color: '#000000', font: '#cecece') - post api('/broadcast_messages', admin), attrs + post api('/broadcast_messages', admin), params: attrs expect(response).to have_gitlab_http_status(201) expect(json_response['color']).to eq attrs[:color] @@ -104,14 +104,14 @@ describe API::BroadcastMessages do describe 'PUT /broadcast_messages/:id' do it 'returns a 401 for anonymous users' do put api("/broadcast_messages/#{message.id}"), - attributes_for(:broadcast_message) + params: attributes_for(:broadcast_message) expect(response).to have_gitlab_http_status(401) end it 'returns a 403 for users' do put api("/broadcast_messages/#{message.id}", user), - attributes_for(:broadcast_message) + params: attributes_for(:broadcast_message) expect(response).to have_gitlab_http_status(403) end @@ -120,7 +120,7 @@ describe API::BroadcastMessages do it 'accepts new background and foreground colors' do attrs = { color: '#000000', font: '#cecece' } - put api("/broadcast_messages/#{message.id}", admin), attrs + put api("/broadcast_messages/#{message.id}", admin), params: attrs expect(response).to have_gitlab_http_status(200) expect(json_response['color']).to eq attrs[:color] @@ -132,7 +132,7 @@ describe API::BroadcastMessages do travel_to(time) do attrs = { starts_at: Time.zone.now, ends_at: 3.hours.from_now } - put api("/broadcast_messages/#{message.id}", admin), attrs + put api("/broadcast_messages/#{message.id}", admin), params: attrs expect(response).to have_gitlab_http_status(200) expect(json_response['starts_at']).to eq '2016-07-02T10:11:12.000Z' @@ -143,7 +143,7 @@ describe API::BroadcastMessages do it 'accepts a new message' do attrs = { message: 'new message' } - put api("/broadcast_messages/#{message.id}", admin), attrs + put api("/broadcast_messages/#{message.id}", admin), params: attrs expect(response).to have_gitlab_http_status(200) expect { message.reload }.to change { message.message }.to('new message') @@ -154,14 +154,14 @@ describe API::BroadcastMessages do describe 'DELETE /broadcast_messages/:id' do it 'returns a 401 for anonymous users' do delete api("/broadcast_messages/#{message.id}"), - attributes_for(:broadcast_message) + params: attributes_for(:broadcast_message) expect(response).to have_gitlab_http_status(401) end it 'returns a 403 for users' do delete api("/broadcast_messages/#{message.id}", user), - attributes_for(:broadcast_message) + params: attributes_for(:broadcast_message) expect(response).to have_gitlab_http_status(403) end diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb index a43304c9b83..9388343c392 100644 --- a/spec/requests/api/commit_statuses_spec.rb +++ b/spec/requests/api/commit_statuses_spec.rb @@ -51,7 +51,7 @@ describe API::CommitStatuses do context 'all commit statuses' do before do - get api(get_url, reporter), all: 1 + get api(get_url, reporter), params: { all: 1 } end it 'returns all commit statuses' do @@ -66,7 +66,7 @@ describe API::CommitStatuses do context 'latest commit statuses for specific ref' do before do - get api(get_url, reporter), ref: 'develop' + get api(get_url, reporter), params: { ref: 'develop' } end it 'returns latest commit statuses for specific ref' do @@ -79,7 +79,7 @@ describe API::CommitStatuses do context 'latest commit statues for specific name' do before do - get api(get_url, reporter), name: 'coverage' + get api(get_url, reporter), params: { name: 'coverage' } end it 'return latest commit statuses for specific name' do @@ -133,7 +133,7 @@ describe API::CommitStatuses do context "for #{status}" do context 'uses only required parameters' do it 'creates commit status' do - post api(post_url, developer), state: status + post api(post_url, developer), params: { state: status } expect(response).to have_gitlab_http_status(201) expect(json_response['sha']).to eq(commit.id) @@ -153,12 +153,12 @@ describe API::CommitStatuses do context 'transitions status from pending' do before do - post api(post_url, developer), state: 'pending' + post api(post_url, developer), params: { state: 'pending' } end %w[running success failed canceled].each do |status| it "to #{status}" do - expect { post api(post_url, developer), state: status }.not_to change { CommitStatus.count } + expect { post api(post_url, developer), params: { state: status } }.not_to change { CommitStatus.count } expect(response).to have_gitlab_http_status(201) expect(json_response['status']).to eq(status) @@ -169,7 +169,7 @@ describe API::CommitStatuses do context 'with all optional parameters' do context 'when creating a commit status' do subject do - post api(post_url, developer), { + post api(post_url, developer), params: { state: 'success', context: 'coverage', ref: 'master', @@ -206,7 +206,7 @@ describe API::CommitStatuses do context 'when updatig a commit status' do before do - post api(post_url, developer), { + post api(post_url, developer), params: { state: 'running', context: 'coverage', ref: 'master', @@ -215,7 +215,7 @@ describe API::CommitStatuses do target_url: 'http://gitlab.com/status' } - post api(post_url, developer), { + post api(post_url, developer), params: { state: 'success', name: 'coverage', ref: 'master', @@ -244,10 +244,10 @@ describe API::CommitStatuses do context 'when retrying a commit status' do before do post api(post_url, developer), - { state: 'failed', name: 'test', ref: 'master' } + params: { state: 'failed', name: 'test', ref: 'master' } post api(post_url, developer), - { state: 'success', name: 'test', ref: 'master' } + params: { state: 'success', name: 'test', ref: 'master' } end it 'correctly posts a new commit status' do @@ -265,7 +265,7 @@ describe API::CommitStatuses do context 'when status is invalid' do before do - post api(post_url, developer), state: 'invalid' + post api(post_url, developer), params: { state: 'invalid' } end it 'does not create commit status' do @@ -287,7 +287,7 @@ describe API::CommitStatuses do let(:sha) { 'invalid_sha' } before do - post api(post_url, developer), state: 'running' + post api(post_url, developer), params: { state: 'running' } end it 'returns not found error' do @@ -297,8 +297,10 @@ describe API::CommitStatuses do context 'when target URL is an invalid address' do before do - post api(post_url, developer), state: 'pending', - target_url: 'invalid url' + post api(post_url, developer), params: { + state: 'pending', + target_url: 'invalid url' + } end it 'responds with bad request status and validation errors' do @@ -311,7 +313,7 @@ describe API::CommitStatuses do context 'reporter user' do before do - post api(post_url, reporter), state: 'running' + post api(post_url, reporter), params: { state: 'running' } end it 'does not create commit status' do @@ -321,7 +323,7 @@ describe API::CommitStatuses do context 'guest user' do before do - post api(post_url, guest), state: 'running' + post api(post_url, guest), params: { state: 'running' } end it 'does not create commit status' do diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb index 9e599c2175f..6b9bc6eda6a 100644 --- a/spec/requests/api/commits_spec.rb +++ b/spec/requests/api/commits_spec.rb @@ -281,11 +281,11 @@ describe API::Commits do it 'does not increment the usage counters using access token authentication' do expect(::Gitlab::WebIdeCommitsCounter).not_to receive(:increment) - post api(url, user), valid_c_params + post api(url, user), params: valid_c_params end it 'a new file in project repo' do - post api(url, user), valid_c_params + post api(url, user), params: valid_c_params expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq(message) @@ -294,7 +294,7 @@ describe API::Commits do end it 'a new file with utf8 chars in project repo' do - post api(url, user), valid_utf8_c_params + post api(url, user), params: valid_utf8_c_params expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq(message) @@ -303,7 +303,7 @@ describe API::Commits do end it 'returns a 400 bad request if file exists' do - post api(url, user), invalid_c_params + post api(url, user), params: invalid_c_params expect(response).to have_gitlab_http_status(400) end @@ -312,7 +312,7 @@ describe API::Commits do let(:url) { "/projects/#{CGI.escape(project.full_path)}/repository/commits" } it 'a new file in project repo' do - post api(url, user), valid_c_params + post api(url, user), params: valid_c_params expect(response).to have_gitlab_http_status(201) end @@ -347,14 +347,14 @@ describe API::Commits do end it 'an existing file in project repo' do - post api(url, user), valid_d_params + post api(url, user), params: valid_d_params expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq(message) end it 'returns a 400 bad request if file does not exist' do - post api(url, user), invalid_d_params + post api(url, user), params: invalid_d_params expect(response).to have_gitlab_http_status(400) end @@ -392,14 +392,14 @@ describe API::Commits do end it 'an existing file in project repo' do - post api(url, user), valid_m_params + post api(url, user), params: valid_m_params expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq(message) end it 'returns a 400 bad request if file does not exist' do - post api(url, user), invalid_m_params + post api(url, user), params: invalid_m_params expect(response).to have_gitlab_http_status(400) end @@ -435,14 +435,14 @@ describe API::Commits do end it 'an existing file in project repo' do - post api(url, user), valid_u_params + post api(url, user), params: valid_u_params expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq(message) end it 'returns a 400 bad request if file does not exist' do - post api(url, user), invalid_u_params + post api(url, user), params: invalid_u_params expect(response).to have_gitlab_http_status(400) end @@ -467,7 +467,7 @@ describe API::Commits do end it 'responds with success' do - post api(url, user), params + post api(url, user), params: params expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq(message) @@ -477,7 +477,7 @@ describe API::Commits do let(:execute_filemode) { false } it 'responds with success' do - post api(url, user), params + post api(url, user), params: params expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq(message) @@ -488,7 +488,7 @@ describe API::Commits do let(:file_path) { 'foo/bar.baz' } it "responds with 400" do - post api(url, user), params + post api(url, user), params: params expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq("A file with this name doesn't exist") @@ -566,28 +566,28 @@ describe API::Commits do end it 'are committed as one in project repo' do - post api(url, user), valid_mo_params + post api(url, user), params: valid_mo_params expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq(message) end it 'includes the commit stats' do - post api(url, user), valid_mo_params + post api(url, user), params: valid_mo_params expect(response).to have_gitlab_http_status(201) expect(json_response).to include 'stats' end it "doesn't include the commit stats when stats is false" do - post api(url, user), valid_mo_params.merge(stats: false) + post api(url, user), params: valid_mo_params.merge(stats: false) expect(response).to have_gitlab_http_status(201) expect(json_response).not_to include 'stats' end it 'return a 400 bad request if there are any issues' do - post api(url, user), invalid_mo_params + post api(url, user), params: invalid_mo_params expect(response).to have_gitlab_http_status(400) end @@ -613,13 +613,13 @@ describe API::Commits do end it 'allows pushing to the source branch of the merge request' do - post api(url, user), push_params('feature') + post api(url, user), params: push_params('feature') expect(response).to have_gitlab_http_status(:created) end it 'denies pushing to another branch' do - post api(url, user), push_params('other-branch') + post api(url, user), params: push_params('other-branch') expect(response).to have_gitlab_http_status(:forbidden) end @@ -651,7 +651,7 @@ describe API::Commits do context 'for a valid commit' do it 'returns all refs with no scope' do - get api(route, current_user), per_page: 100 + get api(route, current_user), params: { per_page: 100 } refs = project.repository.branch_names_contains(commit_id).map {|name| ['branch', name]} refs.concat(project.repository.tag_names_contains(commit_id).map {|name| ['tag', name]}) @@ -663,7 +663,7 @@ describe API::Commits do end it 'returns all refs' do - get api(route, current_user), type: 'all', per_page: 100 + get api(route, current_user), params: { type: 'all', per_page: 100 } refs = project.repository.branch_names_contains(commit_id).map {|name| ['branch', name]} refs.concat(project.repository.tag_names_contains(commit_id).map {|name| ['tag', name]}) @@ -673,7 +673,7 @@ describe API::Commits do end it 'returns the branch refs' do - get api(route, current_user), type: 'branch', per_page: 100 + get api(route, current_user), params: { type: 'branch', per_page: 100 } refs = project.repository.branch_names_contains(commit_id).map {|name| ['branch', name]} @@ -682,7 +682,7 @@ describe API::Commits do end it 'returns the tag refs' do - get api(route, current_user), type: 'tag', per_page: 100 + get api(route, current_user), params: { type: 'tag', per_page: 100 } refs = project.repository.tag_names_contains(commit_id).map {|name| ['tag', name]} @@ -750,14 +750,14 @@ describe API::Commits do end it "is false it does not include stats" do - get api(route, user), stats: false + get api(route, user), params: { stats: false } expect(response).to have_gitlab_http_status(200) expect(json_response).not_to include 'stats' end it "is true it includes stats" do - get api(route, user), stats: true + get api(route, user), params: { stats: true } expect(response).to have_gitlab_http_status(200) expect(json_response).to include 'stats' @@ -1063,7 +1063,7 @@ describe API::Commits do shared_examples_for 'ref cherry-pick' do context 'when ref exists' do it 'cherry-picks the ref commit' do - post api(route, current_user), branch: branch + post api(route, current_user), params: { branch: branch } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/commit/basic') @@ -1078,7 +1078,7 @@ describe API::Commits do include_context 'disabled repository' it_behaves_like '403 response' do - let(:request) { post api(route, current_user), branch: 'master' } + let(:request) { post api(route, current_user), params: { branch: 'master' } } end end end @@ -1087,13 +1087,13 @@ describe API::Commits do let(:project) { create(:project, :public, :repository) } it_behaves_like '403 response' do - let(:request) { post api(route), branch: 'master' } + let(:request) { post api(route), params: { branch: 'master' } } end end context 'when unauthenticated', 'and project is private' do it_behaves_like '404 response' do - let(:request) { post api(route), branch: 'master' } + let(:request) { post api(route), params: { branch: 'master' } } let(:message) { '404 Project Not Found' } end end @@ -1107,7 +1107,7 @@ describe API::Commits do let(:commit_id) { 'unknown' } it_behaves_like '404 response' do - let(:request) { post api(route, current_user), branch: 'master' } + let(:request) { post api(route, current_user), params: { branch: 'master' } } let(:message) { '404 Commit Not Found' } end end @@ -1121,21 +1121,21 @@ describe API::Commits do context 'when branch is empty' do ['', ' '].each do |branch| it_behaves_like '400 response' do - let(:request) { post api(route, current_user), branch: branch } + let(:request) { post api(route, current_user), params: { branch: branch } } end end end context 'when branch does not exist' do it_behaves_like '404 response' do - let(:request) { post api(route, current_user), branch: 'foo' } + let(:request) { post api(route, current_user), params: { branch: 'foo' } } let(:message) { '404 Branch Not Found' } end end context 'when commit is already included in the target branch' do it_behaves_like '400 response' do - let(:request) { post api(route, current_user), branch: 'markdown' } + let(:request) { post api(route, current_user), params: { branch: 'markdown' } } end end @@ -1150,7 +1150,7 @@ describe API::Commits do let(:commit_id) { branch_with_slash.name } it_behaves_like '404 response' do - let(:request) { post api(route, current_user), branch: 'master' } + let(:request) { post api(route, current_user), params: { branch: 'master' } } end end @@ -1181,7 +1181,7 @@ describe API::Commits do end it 'returns 400 if you are not allowed to push to the target branch' do - post api(route, current_user), branch: 'feature' + post api(route, current_user), params: { branch: 'feature' } expect(response).to have_gitlab_http_status(:forbidden) expect(json_response['message']).to match(/You are not allowed to push into this branch/) @@ -1195,13 +1195,13 @@ describe API::Commits do let(:project_id) { forked_project.id } it 'allows access from a maintainer that to the source branch' do - post api(route, user), branch: 'feature' + post api(route, user), params: { branch: 'feature' } expect(response).to have_gitlab_http_status(:created) end it 'denies cherry picking to another branch' do - post api(route, user), branch: 'master' + post api(route, user), params: { branch: 'master' } expect(response).to have_gitlab_http_status(:forbidden) end @@ -1217,7 +1217,7 @@ describe API::Commits do shared_examples_for 'ref revert' do context 'when ref exists' do it 'reverts the ref commit' do - post api(route, current_user), branch: branch + post api(route, current_user), params: { branch: branch } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/commit/basic') @@ -1233,7 +1233,7 @@ describe API::Commits do include_context 'disabled repository' it_behaves_like '403 response' do - let(:request) { post api(route, current_user), branch: branch } + let(:request) { post api(route, current_user), params: { branch: branch } } end end end @@ -1242,13 +1242,13 @@ describe API::Commits do let(:project) { create(:project, :public, :repository) } it_behaves_like '403 response' do - let(:request) { post api(route), branch: branch } + let(:request) { post api(route), params: { branch: branch } } end end context 'when unauthenticated', 'and project is private' do it_behaves_like '404 response' do - let(:request) { post api(route), branch: branch } + let(:request) { post api(route), params: { branch: branch } } let(:message) { '404 Project Not Found' } end end @@ -1262,7 +1262,7 @@ describe API::Commits do let(:commit_id) { 'unknown' } it_behaves_like '404 response' do - let(:request) { post api(route, current_user), branch: branch } + let(:request) { post api(route, current_user), params: { branch: branch } } let(:message) { '404 Commit Not Found' } end end @@ -1276,14 +1276,14 @@ describe API::Commits do context 'when branch is empty' do ['', ' '].each do |branch| it_behaves_like '400 response' do - let(:request) { post api(route, current_user), branch: branch } + let(:request) { post api(route, current_user), params: { branch: branch } } end end end context 'when branch does not exist' do it_behaves_like '404 response' do - let(:request) { post api(route, current_user), branch: 'foo' } + let(:request) { post api(route, current_user), params: { branch: 'foo' } } let(:message) { '404 Branch Not Found' } end end @@ -1311,7 +1311,7 @@ describe API::Commits do end it 'returns 400 if you are not allowed to push to the target branch' do - post api(route, current_user), branch: 'feature' + post api(route, current_user), params: { branch: 'feature' } expect(response).to have_gitlab_http_status(:forbidden) expect(json_response['message']).to match(/You are not allowed to push into this branch/) @@ -1329,7 +1329,7 @@ describe API::Commits do shared_examples_for 'ref new comment' do context 'when ref exists' do it 'creates the comment' do - post api(route, current_user), note: note + post api(route, current_user), params: { note: note } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/commit_note') @@ -1344,7 +1344,7 @@ describe API::Commits do include_context 'disabled repository' it_behaves_like '403 response' do - let(:request) { post api(route, current_user), note: 'My comment' } + let(:request) { post api(route, current_user), params: { note: 'My comment' } } end end end @@ -1353,13 +1353,13 @@ describe API::Commits do let(:project) { create(:project, :public, :repository) } it_behaves_like '400 response' do - let(:request) { post api(route), note: 'My comment' } + let(:request) { post api(route), params: { note: 'My comment' } } end end context 'when unauthenticated', 'and project is private' do it_behaves_like '404 response' do - let(:request) { post api(route), note: 'My comment' } + let(:request) { post api(route), params: { note: 'My comment' } } let(:message) { '404 Project Not Found' } end end @@ -1370,7 +1370,7 @@ describe API::Commits do it_behaves_like 'ref new comment' it 'returns the inline comment' do - post api(route, current_user), note: 'My comment', path: project.repository.commit.raw_diffs.first.new_path, line: 1, line_type: 'new' + post api(route, current_user), params: { note: 'My comment', path: project.repository.commit.raw_diffs.first.new_path, line: 1, line_type: 'new' } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/commit_note') @@ -1384,7 +1384,7 @@ describe API::Commits do let(:commit_id) { 'unknown' } it_behaves_like '404 response' do - let(:request) { post api(route, current_user), note: 'My comment' } + let(:request) { post api(route, current_user), params: { note: 'My comment' } } let(:message) { '404 Commit Not Found' } end end @@ -1405,7 +1405,7 @@ describe API::Commits do let(:commit_id) { branch_with_slash.name } it_behaves_like '404 response' do - let(:request) { post api(route, current_user), note: 'My comment' } + let(:request) { post api(route, current_user), params: { note: 'My comment' } } end end diff --git a/spec/requests/api/deploy_keys_spec.rb b/spec/requests/api/deploy_keys_spec.rb index 32fc704a79b..b93ee148736 100644 --- a/spec/requests/api/deploy_keys_spec.rb +++ b/spec/requests/api/deploy_keys_spec.rb @@ -72,14 +72,14 @@ describe API::DeployKeys do describe 'POST /projects/:id/deploy_keys' do it 'does not create an invalid ssh key' do - post api("/projects/#{project.id}/deploy_keys", admin), { title: 'invalid key' } + post api("/projects/#{project.id}/deploy_keys", admin), params: { title: 'invalid key' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('key is missing') end it 'does not create a key without title' do - post api("/projects/#{project.id}/deploy_keys", admin), key: 'some key' + post api("/projects/#{project.id}/deploy_keys", admin), params: { key: 'some key' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('title is missing') @@ -89,7 +89,7 @@ describe API::DeployKeys do key_attrs = attributes_for :another_key expect do - post api("/projects/#{project.id}/deploy_keys", admin), key_attrs + post api("/projects/#{project.id}/deploy_keys", admin), params: key_attrs end.to change { project.deploy_keys.count }.by(1) new_key = project.deploy_keys.last @@ -99,7 +99,7 @@ describe API::DeployKeys do it 'returns an existing ssh key when attempting to add a duplicate' do expect do - post api("/projects/#{project.id}/deploy_keys", admin), { key: deploy_key.key, title: deploy_key.title } + post api("/projects/#{project.id}/deploy_keys", admin), params: { key: deploy_key.key, title: deploy_key.title } end.not_to change { project.deploy_keys.count } expect(response).to have_gitlab_http_status(201) @@ -107,7 +107,7 @@ describe API::DeployKeys do it 'joins an existing ssh key to a new project' do expect do - post api("/projects/#{project2.id}/deploy_keys", admin), { key: deploy_key.key, title: deploy_key.title } + post api("/projects/#{project2.id}/deploy_keys", admin), params: { key: deploy_key.key, title: deploy_key.title } end.to change { project2.deploy_keys.count }.by(1) expect(response).to have_gitlab_http_status(201) @@ -116,7 +116,7 @@ describe API::DeployKeys do it 'accepts can_push parameter' do key_attrs = attributes_for(:another_key).merge(can_push: true) - post api("/projects/#{project.id}/deploy_keys", admin), key_attrs + post api("/projects/#{project.id}/deploy_keys", admin), params: key_attrs expect(response).to have_gitlab_http_status(201) expect(json_response['can_push']).to eq(true) @@ -131,7 +131,7 @@ describe API::DeployKeys do it 'updates a public deploy key as admin' do expect do - put api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", admin), { title: 'new title' } + put api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", admin), params: { title: 'new title' } end.not_to change(deploy_key, :title) expect(response).to have_gitlab_http_status(200) @@ -139,7 +139,7 @@ describe API::DeployKeys do it 'does not update a public deploy key as non admin' do expect do - put api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", user), { title: 'new title' } + put api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", user), params: { title: 'new title' } end.not_to change(deploy_key, :title) expect(response).to have_gitlab_http_status(404) @@ -149,7 +149,7 @@ describe API::DeployKeys do project_private_deploy_key expect do - put api("/projects/#{project.id}/deploy_keys/#{private_deploy_key.id}", admin), { title: '' } + put api("/projects/#{project.id}/deploy_keys/#{private_deploy_key.id}", admin), params: { title: '' } end.not_to change(deploy_key, :title) expect(response).to have_gitlab_http_status(400) @@ -158,7 +158,7 @@ describe API::DeployKeys do it 'updates a private ssh key with correct attributes' do project_private_deploy_key - put api("/projects/#{project.id}/deploy_keys/#{private_deploy_key.id}", admin), { title: 'new title', can_push: true } + put api("/projects/#{project.id}/deploy_keys/#{private_deploy_key.id}", admin), params: { title: 'new title', can_push: true } expect(json_response['id']).to eq(private_deploy_key.id) expect(json_response['title']).to eq('new title') diff --git a/spec/requests/api/doorkeeper_access_spec.rb b/spec/requests/api/doorkeeper_access_spec.rb index 308134eba72..d74484c8d29 100644 --- a/spec/requests/api/doorkeeper_access_spec.rb +++ b/spec/requests/api/doorkeeper_access_spec.rb @@ -7,20 +7,20 @@ describe 'doorkeeper access' do describe "unauthenticated" do it "returns authentication success" do - get api("/user"), access_token: token.token + get api("/user"), params: { access_token: token.token } expect(response).to have_gitlab_http_status(200) end include_examples 'user login request with unique ip limit' do def request - get api('/user'), access_token: token.token + get api('/user'), params: { access_token: token.token } end end end describe "when token invalid" do it "returns authentication error" do - get api("/user"), access_token: "123a" + get api("/user"), params: { access_token: "123a" } expect(response).to have_gitlab_http_status(401) end end @@ -41,7 +41,7 @@ describe 'doorkeeper access' do describe "when user is blocked" do it "returns authorization error" do user.block - get api("/user"), access_token: token.token + get api("/user"), params: { access_token: token.token } expect(response).to have_gitlab_http_status(403) end @@ -50,7 +50,7 @@ describe 'doorkeeper access' do describe "when user is ldap_blocked" do it "returns authorization error" do user.ldap_block - get api("/user"), access_token: token.token + get api("/user"), params: { access_token: token.token } expect(response).to have_gitlab_http_status(403) end diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb index f3db0c122a0..493d3642255 100644 --- a/spec/requests/api/environments_spec.rb +++ b/spec/requests/api/environments_spec.rb @@ -47,7 +47,7 @@ describe API::Environments do describe 'POST /projects/:id/environments' do context 'as a member' do it 'creates a environment with valid params' do - post api("/projects/#{project.id}/environments", user), name: "mepmep" + post api("/projects/#{project.id}/environments", user), params: { name: "mepmep" } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq('mepmep') @@ -56,19 +56,19 @@ describe API::Environments do end it 'requires name to be passed' do - post api("/projects/#{project.id}/environments", user), external_url: 'test.gitlab.com' + post api("/projects/#{project.id}/environments", user), params: { external_url: 'test.gitlab.com' } expect(response).to have_gitlab_http_status(400) end it 'returns a 400 if environment already exists' do - post api("/projects/#{project.id}/environments", user), name: environment.name + post api("/projects/#{project.id}/environments", user), params: { name: environment.name } expect(response).to have_gitlab_http_status(400) end it 'returns a 400 if slug is specified' do - post api("/projects/#{project.id}/environments", user), name: "foo", slug: "foo" + post api("/projects/#{project.id}/environments", user), params: { name: "foo", slug: "foo" } expect(response).to have_gitlab_http_status(400) expect(json_response["error"]).to eq("slug is automatically generated and cannot be changed") @@ -77,13 +77,13 @@ describe API::Environments do context 'a non member' do it 'rejects the request' do - post api("/projects/#{project.id}/environments", non_member), name: 'gitlab.com' + post api("/projects/#{project.id}/environments", non_member), params: { name: 'gitlab.com' } expect(response).to have_gitlab_http_status(404) end it 'returns a 400 when the required params are missing' do - post api("/projects/12345/environments", non_member), external_url: 'http://env.git.com' + post api("/projects/12345/environments", non_member), params: { external_url: 'http://env.git.com' } end end end @@ -92,7 +92,7 @@ describe API::Environments do it 'returns a 200 if name and external_url are changed' do url = 'https://mepmep.whatever.ninja' put api("/projects/#{project.id}/environments/#{environment.id}", user), - name: 'Mepmep', external_url: url + params: { name: 'Mepmep', external_url: url } expect(response).to have_gitlab_http_status(200) expect(json_response['name']).to eq('Mepmep') @@ -102,7 +102,7 @@ describe API::Environments do it "won't allow slug to be changed" do slug = environment.slug api_url = api("/projects/#{project.id}/environments/#{environment.id}", user) - put api_url, slug: slug + "-foo" + put api_url, params: { slug: slug + "-foo" } expect(response).to have_gitlab_http_status(400) expect(json_response["error"]).to eq("slug is automatically generated and cannot be changed") @@ -111,7 +111,7 @@ describe API::Environments do it "won't update the external_url if only the name is passed" do url = environment.external_url put api("/projects/#{project.id}/environments/#{environment.id}", user), - name: 'Mepmep' + params: { name: 'Mepmep' } expect(response).to have_gitlab_http_status(200) expect(json_response['name']).to eq('Mepmep') diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb index 573eebe314d..0ac23505de7 100644 --- a/spec/requests/api/events_spec.rb +++ b/spec/requests/api/events_spec.rb @@ -182,6 +182,68 @@ describe API::Events do end end + context 'with inaccessible events' do + let(:public_project) { create(:project, :public, creator_id: user.id, namespace: user.namespace) } + let(:confidential_issue) { create(:closed_issue, confidential: true, project: public_project, author: user) } + let!(:confidential_event) { create(:event, project: public_project, author: user, target: confidential_issue, action: Event::CLOSED) } + let(:public_issue) { create(:closed_issue, project: public_project, author: user) } + let!(:public_event) { create(:event, project: public_project, author: user, target: public_issue, action: Event::CLOSED) } + + it 'returns only accessible events' do + get api("/projects/#{public_project.id}/events", non_member) + + expect(response).to have_gitlab_http_status(200) + expect(json_response.size).to eq(1) + end + + it 'returns all events when the user has access' do + get api("/projects/#{public_project.id}/events", user) + + expect(response).to have_gitlab_http_status(200) + expect(json_response.size).to eq(2) + end + end + + context 'pagination' do + let(:public_project) { create(:project, :public) } + + before do + create(:event, + project: public_project, + target: create(:issue, project: public_project, title: 'Issue 1'), + action: Event::CLOSED, + created_at: Date.parse('2018-12-10')) + create(:event, + project: public_project, + target: create(:issue, confidential: true, project: public_project, title: 'Confidential event'), + action: Event::CLOSED, + created_at: Date.parse('2018-12-11')) + create(:event, + project: public_project, + target: create(:issue, project: public_project, title: 'Issue 2'), + action: Event::CLOSED, + created_at: Date.parse('2018-12-12')) + end + + it 'correctly returns the second page without inaccessible events' do + get api("/projects/#{public_project.id}/events", user), params: { per_page: 2, page: 2 } + + titles = json_response.map { |event| event['target_title'] } + + expect(titles.first).to eq('Issue 1') + expect(titles).not_to include('Confidential event') + end + + it 'correctly returns the first page without inaccessible events' do + get api("/projects/#{public_project.id}/events", user), params: { per_page: 2, page: 1 } + + titles = json_response.map { |event| event['target_title'] } + + expect(titles.first).to eq('Issue 2') + expect(titles).not_to include('Confidential event') + end + end + context 'when not permitted to read' do it 'returns 404' do get api("/projects/#{private_project.id}/events", non_member) @@ -217,13 +279,13 @@ describe API::Events do it 'avoids N+1 queries' do control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do - get api("/projects/#{private_project.id}/events", user), target_type: :merge_request + get api("/projects/#{private_project.id}/events", user), params: { target_type: :merge_request } end.count create_event(merge_request2) expect do - get api("/projects/#{private_project.id}/events", user), target_type: :merge_request + get api("/projects/#{private_project.id}/events", user), params: { target_type: :merge_request } end.not_to exceed_all_query_limit(control_count) expect(response).to have_gitlab_http_status(200) diff --git a/spec/requests/api/features_spec.rb b/spec/requests/api/features_spec.rb index c5354c2d639..7d3eff7d32d 100644 --- a/spec/requests/api/features_spec.rb +++ b/spec/requests/api/features_spec.rb @@ -79,7 +79,7 @@ describe API::Features do context 'when passed value=true' do it 'creates an enabled feature' do - post api("/features/#{feature_name}", admin), value: 'true' + post api("/features/#{feature_name}", admin), params: { value: 'true' } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -89,7 +89,7 @@ describe API::Features do end it 'creates an enabled feature for the given Flipper group when passed feature_group=perf_team' do - post api("/features/#{feature_name}", admin), value: 'true', feature_group: 'perf_team' + post api("/features/#{feature_name}", admin), params: { value: 'true', feature_group: 'perf_team' } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -102,7 +102,7 @@ describe API::Features do end it 'creates an enabled feature for the given user when passed user=username' do - post api("/features/#{feature_name}", admin), value: 'true', user: user.username + post api("/features/#{feature_name}", admin), params: { value: 'true', user: user.username } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -115,7 +115,7 @@ describe API::Features do end it 'creates an enabled feature for the given user and feature group when passed user=username and feature_group=perf_team' do - post api("/features/#{feature_name}", admin), value: 'true', user: user.username, feature_group: 'perf_team' + post api("/features/#{feature_name}", admin), params: { value: 'true', user: user.username, feature_group: 'perf_team' } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -130,7 +130,7 @@ describe API::Features do end it 'creates a feature with the given percentage if passed an integer' do - post api("/features/#{feature_name}", admin), value: '50' + post api("/features/#{feature_name}", admin), params: { value: '50' } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -152,7 +152,7 @@ describe API::Features do context 'when passed value=true' do it 'enables the feature' do - post api("/features/#{feature_name}", admin), value: 'true' + post api("/features/#{feature_name}", admin), params: { value: 'true' } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -162,7 +162,7 @@ describe API::Features do end it 'enables the feature for the given Flipper group when passed feature_group=perf_team' do - post api("/features/#{feature_name}", admin), value: 'true', feature_group: 'perf_team' + post api("/features/#{feature_name}", admin), params: { value: 'true', feature_group: 'perf_team' } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -175,7 +175,7 @@ describe API::Features do end it 'enables the feature for the given user when passed user=username' do - post api("/features/#{feature_name}", admin), value: 'true', user: user.username + post api("/features/#{feature_name}", admin), params: { value: 'true', user: user.username } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -193,7 +193,7 @@ describe API::Features do feature.enable expect(feature).to be_enabled - post api("/features/#{feature_name}", admin), value: 'false' + post api("/features/#{feature_name}", admin), params: { value: 'false' } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -206,7 +206,7 @@ describe API::Features do feature.enable(Feature.group(:perf_team)) expect(Feature.get(feature_name).enabled?(admin)).to be_truthy - post api("/features/#{feature_name}", admin), value: 'false', feature_group: 'perf_team' + post api("/features/#{feature_name}", admin), params: { value: 'false', feature_group: 'perf_team' } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -219,7 +219,7 @@ describe API::Features do feature.enable(user) expect(Feature.get(feature_name).enabled?(user)).to be_truthy - post api("/features/#{feature_name}", admin), value: 'false', user: user.username + post api("/features/#{feature_name}", admin), params: { value: 'false', user: user.username } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( @@ -235,7 +235,7 @@ describe API::Features do end it 'updates the percentage of time if passed an integer' do - post api("/features/#{feature_name}", admin), value: '30' + post api("/features/#{feature_name}", admin), params: { value: '30' } expect(response).to have_gitlab_http_status(201) expect(json_response).to eq( diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb index 620f9f5e1d6..a0aee937185 100644 --- a/spec/requests/api/files_spec.rb +++ b/spec/requests/api/files_spec.rb @@ -54,7 +54,7 @@ describe API::Files do describe "HEAD /projects/:id/repository/files/:file_path" do shared_examples_for 'repository files' do it 'returns file attributes in headers' do - head api(route(file_path), current_user), params + head api(route(file_path), current_user), params: params expect(response).to have_gitlab_http_status(200) expect(response.headers['X-Gitlab-File-Path']).to eq(CGI.unescape(file_path)) @@ -68,7 +68,7 @@ describe API::Files do file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee" params[:ref] = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9" - head api(route(file_path), current_user), params + head api(route(file_path), current_user), params: params expect(response).to have_gitlab_http_status(200) expect(response.headers['X-Gitlab-File-Name']).to eq('commit.js.coffee') @@ -87,7 +87,7 @@ describe API::Files do it "responds with a 404 status" do params[:ref] = 'master' - head api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params + head api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params: params expect(response).to have_gitlab_http_status(404) end @@ -97,7 +97,7 @@ describe API::Files do include_context 'disabled repository' it "responds with a 403 status" do - head api(route(file_path), current_user), params + head api(route(file_path), current_user), params: params expect(response).to have_gitlab_http_status(403) end @@ -115,7 +115,7 @@ describe API::Files do it "responds with a 404 status" do current_user = nil - head api(route(file_path), current_user), params + head api(route(file_path), current_user), params: params expect(response).to have_gitlab_http_status(404) end @@ -136,7 +136,7 @@ describe API::Files do context 'when authenticated', 'as a guest' do it_behaves_like '403 response' do - let(:request) { head api(route(file_path), guest), params } + let(:request) { head api(route(file_path), guest), params: params } end end end @@ -144,7 +144,7 @@ describe API::Files do describe "GET /projects/:id/repository/files/:file_path" do shared_examples_for 'repository files' do it 'returns file attributes as json' do - get api(route(file_path), current_user), params + get api(route(file_path), current_user), params: params expect(response).to have_gitlab_http_status(200) expect(json_response['file_path']).to eq(CGI.unescape(file_path)) @@ -157,7 +157,7 @@ describe API::Files do it 'returns json when file has txt extension' do file_path = "bar%2Fbranch-test.txt" - get api(route(file_path), current_user), params + get api(route(file_path), current_user), params: params expect(response).to have_gitlab_http_status(200) expect(response.content_type).to eq('application/json') @@ -168,7 +168,7 @@ describe API::Files do file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee" params[:ref] = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9" - get api(route(file_path), current_user), params + get api(route(file_path), current_user), params: params expect(response).to have_gitlab_http_status(200) expect(json_response['file_name']).to eq('commit.js.coffee') @@ -180,7 +180,7 @@ describe API::Files do url = route(file_path) + "/raw" expect(Gitlab::Workhorse).to receive(:send_git_blob) - get api(url, current_user), params + get api(url, current_user), params: params expect(response).to have_gitlab_http_status(200) end @@ -188,9 +188,9 @@ describe API::Files do it 'forces attachment content disposition' do url = route(file_path) + "/raw" - get api(url, current_user), params + get api(url, current_user), params: params - expect(headers['Content-Disposition']).to match(/^attachment/) + expect(headers['Content-Disposition']).to eq('attachment; filename="popen.rb"') end context 'when mandatory params are not given' do @@ -203,7 +203,7 @@ describe API::Files do let(:params) { { ref: 'master' } } it_behaves_like '404 response' do - let(:request) { get api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params } + let(:request) { get api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params: params } let(:message) { '404 File Not Found' } end end @@ -212,7 +212,7 @@ describe API::Files do include_context 'disabled repository' it_behaves_like '403 response' do - let(:request) { get api(route(file_path), current_user), params } + let(:request) { get api(route(file_path), current_user), params: params } end end end @@ -233,7 +233,7 @@ describe API::Files do context 'when unauthenticated', 'and project is private' do it_behaves_like '404 response' do - let(:request) { get api(route(file_path)), params } + let(:request) { get api(route(file_path)), params: params } let(:message) { '404 Project Not Found' } end end @@ -246,7 +246,7 @@ describe API::Files do context 'when authenticated', 'as a guest' do it_behaves_like '403 response' do - let(:request) { get api(route(file_path), guest), params } + let(:request) { get api(route(file_path), guest), params: params } end end end @@ -257,7 +257,7 @@ describe API::Files do url = route(file_path) + "/raw" expect(Gitlab::Workhorse).to receive(:send_git_blob) - get api(url, current_user), params + get api(url, current_user), params: params expect(response).to have_gitlab_http_status(200) end @@ -266,7 +266,7 @@ describe API::Files do url = route('.gitignore') + "/raw" expect(Gitlab::Workhorse).to receive(:send_git_blob) - get api(url, current_user), params + get api(url, current_user), params: params expect(response).to have_gitlab_http_status(200) end @@ -277,7 +277,7 @@ describe API::Files do params[:ref] = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9" expect(Gitlab::Workhorse).to receive(:send_git_blob) - get api(route(file_path) + "/raw", current_user), params + get api(route(file_path) + "/raw", current_user), params: params expect(response).to have_gitlab_http_status(200) end @@ -292,7 +292,7 @@ describe API::Files do let(:params) { { ref: 'master' } } it_behaves_like '404 response' do - let(:request) { get api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params } + let(:request) { get api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params: params } let(:message) { '404 File Not Found' } end end @@ -301,7 +301,7 @@ describe API::Files do include_context 'disabled repository' it_behaves_like '403 response' do - let(:request) { get api(route(file_path), current_user), params } + let(:request) { get api(route(file_path), current_user), params: params } end end end @@ -315,7 +315,7 @@ describe API::Files do context 'when unauthenticated', 'and project is private' do it_behaves_like '404 response' do - let(:request) { get api(route(file_path)), params } + let(:request) { get api(route(file_path)), params: params } let(:message) { '404 Project Not Found' } end end @@ -328,7 +328,7 @@ describe API::Files do context 'when authenticated', 'as a guest' do it_behaves_like '403 response' do - let(:request) { get api(route(file_path), guest), params } + let(:request) { get api(route(file_path), guest), params: params } end end @@ -341,7 +341,7 @@ describe API::Files do params[:ref] = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9" expect(Gitlab::Workhorse).to receive(:send_git_blob) - get api(route(file_path) + "/raw", personal_access_token: token), params + get api(route(file_path) + "/raw", personal_access_token: token), params: params expect(response).to have_gitlab_http_status(200) end @@ -359,7 +359,7 @@ describe API::Files do end it "creates a new file in project repo" do - post api(route(file_path), user), params + post api(route(file_path), user), params: params expect(response).to have_gitlab_http_status(201) expect(json_response["file_path"]).to eq(CGI.unescape(file_path)) @@ -377,7 +377,7 @@ describe API::Files do it 'returns a 400 bad request if the commit message is empty' do params[:commit_message] = '' - post api(route(file_path), user), params + post api(route(file_path), user), params: params expect(response).to have_gitlab_http_status(400) end @@ -386,7 +386,7 @@ describe API::Files do allow_any_instance_of(Repository).to receive(:create_file) .and_raise(Gitlab::Git::CommitError, 'Cannot create file') - post api(route("any%2Etxt"), user), params + post api(route("any%2Etxt"), user), params: params expect(response).to have_gitlab_http_status(400) end @@ -395,7 +395,7 @@ describe API::Files do it 'returns 403 with `read_repository` scope' do token = create(:personal_access_token, scopes: ['read_repository'], user: user) - post api(route(file_path), personal_access_token: token), params + post api(route(file_path), personal_access_token: token), params: params expect(response).to have_gitlab_http_status(403) end @@ -403,7 +403,7 @@ describe API::Files do it 'returns 201 with `api` scope' do token = create(:personal_access_token, scopes: ['api'], user: user) - post api(route(file_path), personal_access_token: token), params + post api(route(file_path), personal_access_token: token), params: params expect(response).to have_gitlab_http_status(201) end @@ -413,7 +413,7 @@ describe API::Files do it "creates a new file with the specified author" do params.merge!(author_email: author_email, author_name: author_name) - post api(route("new_file_with_author%2Etxt"), user), params + post api(route("new_file_with_author%2Etxt"), user), params: params expect(response).to have_gitlab_http_status(201) expect(response.content_type).to eq('application/json') @@ -427,7 +427,7 @@ describe API::Files do let!(:project) { create(:project_empty_repo, namespace: user.namespace ) } it "creates a new file in project repo" do - post api(route("newfile%2Erb"), user), params + post api(route("newfile%2Erb"), user), params: params expect(response).to have_gitlab_http_status(201) expect(json_response['file_path']).to eq('newfile.rb') @@ -448,7 +448,7 @@ describe API::Files do end it "updates existing file in project repo" do - put api(route(file_path), user), params + put api(route(file_path), user), params: params expect(response).to have_gitlab_http_status(200) expect(json_response['file_path']).to eq(CGI.unescape(file_path)) @@ -460,7 +460,7 @@ describe API::Files do it 'returns a 400 bad request if the commit message is empty' do params[:commit_message] = '' - put api(route(file_path), user), params + put api(route(file_path), user), params: params expect(response).to have_gitlab_http_status(400) end @@ -468,7 +468,7 @@ describe API::Files do it "returns a 400 bad request if update existing file with stale last commit id" do params_with_stale_id = params.merge(last_commit_id: 'stale') - put api(route(file_path), user), params_with_stale_id + put api(route(file_path), user), params: params_with_stale_id expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('You are attempting to update a file that has changed since you started editing it.') @@ -479,7 +479,7 @@ describe API::Files do .last_for_path(project.repository, 'master', URI.unescape(file_path)) params_with_correct_id = params.merge(last_commit_id: last_commit.id) - put api(route(file_path), user), params_with_correct_id + put api(route(file_path), user), params: params_with_correct_id expect(response).to have_gitlab_http_status(200) end @@ -494,7 +494,7 @@ describe API::Files do it "updates a file with the specified author" do params.merge!(author_email: author_email, author_name: author_name, content: "New content") - put api(route(file_path), user), params + put api(route(file_path), user), params: params expect(response).to have_gitlab_http_status(200) last_commit = project.repository.commit.raw @@ -513,7 +513,7 @@ describe API::Files do end it "deletes existing file in project repo" do - delete api(route(file_path), user), params + delete api(route(file_path), user), params: params expect(response).to have_gitlab_http_status(204) end @@ -527,7 +527,7 @@ describe API::Files do it 'returns a 400 bad request if the commit message is empty' do params[:commit_message] = '' - delete api(route(file_path), user), params + delete api(route(file_path), user), params: params expect(response).to have_gitlab_http_status(400) end @@ -535,7 +535,7 @@ describe API::Files do it "returns a 400 if fails to delete file" do allow_any_instance_of(Repository).to receive(:delete_file).and_raise(Gitlab::Git::CommitError, 'Cannot delete file') - delete api(route(file_path), user), params + delete api(route(file_path), user), params: params expect(response).to have_gitlab_http_status(400) end @@ -544,7 +544,7 @@ describe API::Files do it "removes a file with the specified author" do params.merge!(author_email: author_email, author_name: author_name) - delete api(route(file_path), user), params + delete api(route(file_path), user), params: params expect(response).to have_gitlab_http_status(204) end @@ -568,11 +568,11 @@ describe API::Files do end before do - post api(route(file_path), user), put_params + post api(route(file_path), user), params: put_params end it "remains unchanged" do - get api(route(file_path), user), get_params + get api(route(file_path), user), params: get_params expect(response).to have_gitlab_http_status(200) expect(json_response['file_path']).to eq(CGI.unescape(file_path)) diff --git a/spec/requests/api/group_boards_spec.rb b/spec/requests/api/group_boards_spec.rb index 894c94688ba..b400a7f55ef 100644 --- a/spec/requests/api/group_boards_spec.rb +++ b/spec/requests/api/group_boards_spec.rb @@ -46,7 +46,7 @@ describe API::GroupBoards do it 'does not create lists for child project labels' do project_label = create(:label, project: project) - post api(url, user), label_id: project_label.id + post api(url, user), params: { label_id: project_label.id } expect(response).to have_gitlab_http_status(400) end diff --git a/spec/requests/api/group_variables_spec.rb b/spec/requests/api/group_variables_spec.rb index f87e035c89d..e52f4c70407 100644 --- a/spec/requests/api/group_variables_spec.rb +++ b/spec/requests/api/group_variables_spec.rb @@ -87,7 +87,7 @@ describe API::GroupVariables do it 'creates variable' do expect do - post api("/groups/#{group.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2', protected: true + post api("/groups/#{group.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'VALUE_2', protected: true } end.to change {group.variables.count}.by(1) expect(response).to have_gitlab_http_status(201) @@ -98,7 +98,7 @@ describe API::GroupVariables do it 'creates variable with optional attributes' do expect do - post api("/groups/#{group.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2' + post api("/groups/#{group.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'VALUE_2' } end.to change {group.variables.count}.by(1) expect(response).to have_gitlab_http_status(201) @@ -109,7 +109,7 @@ describe API::GroupVariables do it 'does not allow to duplicate variable key' do expect do - post api("/groups/#{group.id}/variables", user), key: variable.key, value: 'VALUE_2' + post api("/groups/#{group.id}/variables", user), params: { key: variable.key, value: 'VALUE_2' } end.to change {group.variables.count}.by(0) expect(response).to have_gitlab_http_status(400) @@ -145,7 +145,7 @@ describe API::GroupVariables do initial_variable = group.variables.reload.first value_before = initial_variable.value - put api("/groups/#{group.id}/variables/#{variable.key}", user), value: 'VALUE_1_UP', protected: true + put api("/groups/#{group.id}/variables/#{variable.key}", user), params: { value: 'VALUE_1_UP', protected: true } updated_variable = group.variables.reload.first diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index 688d91113ad..c9dfc5c4a7e 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -60,7 +60,7 @@ describe API::Groups do end it "does not include statistics" do - get api("/groups", user1), statistics: true + get api("/groups", user1), params: { statistics: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -100,7 +100,7 @@ describe API::Groups do project1.statistics.update!(attributes) - get api("/groups", admin), statistics: true + get api("/groups", admin), params: { statistics: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -112,7 +112,7 @@ describe API::Groups do context "when using skip_groups in request" do it "returns all groups excluding skipped groups" do - get api("/groups", admin), skip_groups: [group2.id] + get api("/groups", admin), params: { skip_groups: [group2.id] } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -127,7 +127,7 @@ describe API::Groups do it "returns all groups you have access to" do public_group = create :group, :public - get api("/groups", user1), all_available: true + get api("/groups", user1), params: { all_available: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -159,7 +159,7 @@ describe API::Groups do end it "sorts in descending order when passed" do - get api("/groups", user1), sort: "desc" + get api("/groups", user1), params: { sort: "desc" } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -168,7 +168,7 @@ describe API::Groups do end it "sorts by path in order_by param" do - get api("/groups", user1), order_by: "path" + get api("/groups", user1), params: { order_by: "path" } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -177,7 +177,7 @@ describe API::Groups do end it "sorts by id in the order_by param" do - get api("/groups", user1), order_by: "id" + get api("/groups", user1), params: { order_by: "id" } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -186,7 +186,7 @@ describe API::Groups do end it "sorts also by descending id with pagination fix" do - get api("/groups", user1), order_by: "id", sort: "desc" + get api("/groups", user1), params: { order_by: "id", sort: "desc" } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -195,7 +195,7 @@ describe API::Groups do end it "sorts identical keys by id for good pagination" do - get api("/groups", user1), search: "same-name", order_by: "name" + get api("/groups", user1), params: { search: "same-name", order_by: "name" } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -204,7 +204,7 @@ describe API::Groups do end it "sorts descending identical keys by id for good pagination" do - get api("/groups", user1), search: "same-name", order_by: "name", sort: "desc" + get api("/groups", user1), params: { search: "same-name", order_by: "name", sort: "desc" } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -221,7 +221,7 @@ describe API::Groups do it 'returns an array of groups the user owns' do group1.add_maintainer(user2) - get api('/groups', user2), owned: true + get api('/groups', user2), params: { owned: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -241,7 +241,7 @@ describe API::Groups do end it 'returns an array of groups the user has at least master access' do - get api('/groups', user2), min_access_level: 40 + get api('/groups', user2), params: { min_access_level: 40 } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -344,7 +344,7 @@ describe API::Groups do project = create(:project, namespace: group2, path: 'Foo') create(:project_group_link, project: project, group: group1) - get api("/groups/#{group1.id}", user1), with_projects: false + get api("/groups/#{group1.id}", user1), params: { with_projects: false } expect(response).to have_gitlab_http_status(200) expect(json_response['projects']).to be_nil @@ -426,7 +426,7 @@ describe API::Groups do context 'when authenticated as the group owner' do it 'updates the group' do - put api("/groups/#{group1.id}", user1), name: new_group_name, request_access_enabled: true + put api("/groups/#{group1.id}", user1), params: { name: new_group_name, request_access_enabled: true } expect(response).to have_gitlab_http_status(200) expect(json_response['name']).to eq(new_group_name) @@ -434,7 +434,7 @@ describe API::Groups do end it 'returns 404 for a non existing group' do - put api('/groups/1328', user1), name: new_group_name + put api('/groups/1328', user1), params: { name: new_group_name } expect(response).to have_gitlab_http_status(404) end @@ -442,7 +442,7 @@ describe API::Groups do context 'when authenticated as the admin' do it 'updates the group' do - put api("/groups/#{group1.id}", admin), name: new_group_name + put api("/groups/#{group1.id}", admin), params: { name: new_group_name } expect(response).to have_gitlab_http_status(200) expect(json_response['name']).to eq(new_group_name) @@ -451,7 +451,7 @@ describe API::Groups do context 'when authenticated as an user that can see the group' do it 'does not updates the group' do - put api("/groups/#{group1.id}", user2), name: new_group_name + put api("/groups/#{group1.id}", user2), params: { name: new_group_name } expect(response).to have_gitlab_http_status(403) end @@ -459,7 +459,7 @@ describe API::Groups do context 'when authenticated as an user that cannot see the group' do it 'returns 404 when trying to update the group' do - put api("/groups/#{group2.id}", user1), name: new_group_name + put api("/groups/#{group2.id}", user1), params: { name: new_group_name } expect(response).to have_gitlab_http_status(404) end @@ -480,7 +480,7 @@ describe API::Groups do end it "returns the group's projects with simple representation" do - get api("/groups/#{group1.id}/projects", user1), simple: true + get api("/groups/#{group1.id}/projects", user1), params: { simple: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -493,7 +493,7 @@ describe API::Groups do it "filters the groups projects" do public_project = create(:project, :public, path: 'test1', group: group1) - get api("/groups/#{group1.id}/projects", user1), visibility: 'public' + get api("/groups/#{group1.id}/projects", user1), params: { visibility: 'public' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -507,7 +507,7 @@ describe API::Groups do create(:project_group_link, project: create(:project), group: group1) create(:project_group_link, project: create(:project), group: group1) - get api("/groups/#{group1.id}/projects", user1), with_shared: false + get api("/groups/#{group1.id}/projects", user1), params: { with_shared: false } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -520,7 +520,7 @@ describe API::Groups do create(:project, group: subgroup) create(:project, group: subgroup) - get api("/groups/#{group1.id}/projects", user1), include_subgroups: true + get api("/groups/#{group1.id}/projects", user1), params: { include_subgroups: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -554,7 +554,7 @@ describe API::Groups do it 'only returns the projects owned by user' do project2.group.add_owner(user3) - get api("/groups/#{project2.group.id}/projects", user3), owned: true + get api("/groups/#{project2.group.id}/projects", user3), params: { owned: true } expect(response).to have_gitlab_http_status(200) expect(json_response.length).to eq(1) @@ -564,7 +564,7 @@ describe API::Groups do it 'only returns the projects starred by user' do user1.starred_projects = [project1] - get api("/groups/#{group1.id}/projects", user1), starred: true + get api("/groups/#{group1.id}/projects", user1), params: { starred: true } expect(response).to have_gitlab_http_status(200) expect(json_response.length).to eq(1) @@ -663,7 +663,7 @@ describe API::Groups do context 'when using all_available in request' do it 'returns public subgroups' do - get api("/groups/#{group1.id}/subgroups", user2), all_available: true + get api("/groups/#{group1.id}/subgroups", user2), params: { all_available: true } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -702,7 +702,7 @@ describe API::Groups do context 'when using statistics in request' do it 'does not include statistics' do - get api("/groups/#{group1.id}/subgroups", user2), statistics: true + get api("/groups/#{group1.id}/subgroups", user2), params: { statistics: true } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -754,7 +754,7 @@ describe API::Groups do end it 'includes statistics if requested' do - get api("/groups/#{group1.id}/subgroups", admin), statistics: true + get api("/groups/#{group1.id}/subgroups", admin), params: { statistics: true } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -766,7 +766,7 @@ describe API::Groups do describe "POST /groups" do context "when authenticated as user without group permissions" do it "does not create group" do - post api("/groups", user1), attributes_for(:group) + post api("/groups", user1), params: attributes_for(:group) expect(response).to have_gitlab_http_status(403) end @@ -777,7 +777,7 @@ describe API::Groups do end it 'can create subgroups' do - post api("/groups", user1), parent_id: group2.id, name: 'foo', path: 'foo' + post api("/groups", user1), params: { parent_id: group2.id, name: 'foo', path: 'foo' } expect(response).to have_gitlab_http_status(201) end @@ -789,7 +789,7 @@ describe API::Groups do end it 'cannot create subgroups' do - post api("/groups", user1), parent_id: group2.id, name: 'foo', path: 'foo' + post api("/groups", user1), params: { parent_id: group2.id, name: 'foo', path: 'foo' } expect(response).to have_gitlab_http_status(403) end @@ -800,7 +800,7 @@ describe API::Groups do it "creates group" do group = attributes_for(:group, { request_access_enabled: false }) - post api("/groups", user3), group + post api("/groups", user3), params: group expect(response).to have_gitlab_http_status(201) @@ -815,7 +815,7 @@ describe API::Groups do parent.add_owner(user3) group = attributes_for(:group, { parent_id: parent.id }) - post api("/groups", user3), group + post api("/groups", user3), params: group expect(response).to have_gitlab_http_status(201) @@ -824,20 +824,20 @@ describe API::Groups do end it "does not create group, duplicate" do - post api("/groups", user3), { name: 'Duplicate Test', path: group2.path } + post api("/groups", user3), params: { name: 'Duplicate Test', path: group2.path } expect(response).to have_gitlab_http_status(400) expect(response.message).to eq("Bad Request") end it "returns 400 bad request error if name not given" do - post api("/groups", user3), { path: group2.path } + post api("/groups", user3), params: { path: group2.path } expect(response).to have_gitlab_http_status(400) end it "returns 400 bad request error if path not given" do - post api("/groups", user3), { name: 'test' } + post api("/groups", user3), params: { name: 'test' } expect(response).to have_gitlab_http_status(400) end diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb index f7916441313..a0c64d295c0 100644 --- a/spec/requests/api/helpers_spec.rb +++ b/spec/requests/api/helpers_spec.rb @@ -283,7 +283,7 @@ describe API::Helpers do it 'sends the params, excluding confidential values' do expect(ProjectsFinder).to receive(:new).and_raise('Runtime Error!') - get api('/projects', user), password: 'dont_send_this', other_param: 'send_this' + get api('/projects', user), params: { password: 'dont_send_this', other_param: 'send_this' } expect(event_data).to include('other_param=send_this') expect(event_data).to include('password=********') diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index 2ebcb787d06..589816b5d8f 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -12,7 +12,7 @@ describe API::Internal do it do expect_any_instance_of(Redis).to receive(:ping).and_return('PONG') - get api("/internal/check"), secret_token: secret_token + get api("/internal/check"), params: { secret_token: secret_token } expect(response).to have_gitlab_http_status(200) expect(json_response['api_version']).to eq(API::API.version) @@ -22,7 +22,7 @@ describe API::Internal do it 'returns false for field `redis` when redis is unavailable' do expect_any_instance_of(Redis).to receive(:ping).and_raise(Errno::ENOENT) - get api("/internal/check"), secret_token: secret_token + get api("/internal/check"), params: { secret_token: secret_token } expect(json_response['redis']).to be(false) end @@ -33,7 +33,7 @@ describe API::Internal do let!(:broadcast_message) { create(:broadcast_message, starts_at: 1.day.ago, ends_at: 1.day.from_now ) } it 'returns one broadcast message' do - get api('/internal/broadcast_message'), secret_token: secret_token + get api('/internal/broadcast_message'), params: { secret_token: secret_token } expect(response).to have_gitlab_http_status(200) expect(json_response['message']).to eq(broadcast_message.message) @@ -42,7 +42,7 @@ describe API::Internal do context 'broadcast message does not exist' do it 'returns nothing' do - get api('/internal/broadcast_message'), secret_token: secret_token + get api('/internal/broadcast_message'), params: { secret_token: secret_token } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_empty @@ -53,7 +53,7 @@ describe API::Internal do it 'returns nothing' do allow(BroadcastMessage).to receive(:current).and_return(nil) - get api('/internal/broadcast_message'), secret_token: secret_token + get api('/internal/broadcast_message'), params: { secret_token: secret_token } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_empty @@ -66,7 +66,7 @@ describe API::Internal do let!(:broadcast_message) { create(:broadcast_message, starts_at: 1.day.ago, ends_at: 1.day.from_now ) } it 'returns active broadcast message(s)' do - get api('/internal/broadcast_messages'), secret_token: secret_token + get api('/internal/broadcast_messages'), params: { secret_token: secret_token } expect(response).to have_gitlab_http_status(200) expect(json_response[0]['message']).to eq(broadcast_message.message) @@ -75,7 +75,7 @@ describe API::Internal do context 'broadcast message does not exist' do it 'returns nothing' do - get api('/internal/broadcast_messages'), secret_token: secret_token + get api('/internal/broadcast_messages'), params: { secret_token: secret_token } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_empty @@ -86,8 +86,10 @@ describe API::Internal do describe 'GET /internal/two_factor_recovery_codes' do it 'returns an error message when the key does not exist' do post api('/internal/two_factor_recovery_codes'), - secret_token: secret_token, - key_id: 12345 + params: { + secret_token: secret_token, + key_id: 12345 + } expect(json_response['success']).to be_falsey expect(json_response['message']).to eq('Could not find the given key') @@ -97,8 +99,10 @@ describe API::Internal do deploy_key = create(:deploy_key) post api('/internal/two_factor_recovery_codes'), - secret_token: secret_token, - key_id: deploy_key.id + params: { + secret_token: secret_token, + key_id: deploy_key.id + } expect(json_response['success']).to be_falsey expect(json_response['message']).to eq('Deploy keys cannot be used to retrieve recovery codes') @@ -108,8 +112,10 @@ describe API::Internal do key_without_user = create(:key, user: nil) post api('/internal/two_factor_recovery_codes'), - secret_token: secret_token, - key_id: key_without_user.id + params: { + secret_token: secret_token, + key_id: key_without_user.id + } expect(json_response['success']).to be_falsey expect(json_response['message']).to eq('Could not find a user for the given key') @@ -123,8 +129,10 @@ describe API::Internal do .to receive(:generate_otp_backup_codes!).and_return(%w(119135e5a3ebce8e 34bd7b74adbc8861)) post api('/internal/two_factor_recovery_codes'), - secret_token: secret_token, - key_id: key.id + params: { + secret_token: secret_token, + key_id: key.id + } expect(json_response['success']).to be_truthy expect(json_response['recovery_codes']).to match_array(%w(119135e5a3ebce8e 34bd7b74adbc8861)) @@ -136,8 +144,10 @@ describe API::Internal do allow_any_instance_of(User).to receive(:two_factor_enabled?).and_return(false) post api('/internal/two_factor_recovery_codes'), - secret_token: secret_token, - key_id: key.id + params: { + secret_token: secret_token, + key_id: key.id + } expect(json_response['success']).to be_falsey expect(json_response['recovery_codes']).to be_nil @@ -156,9 +166,8 @@ describe API::Internal do expect(response).to have_gitlab_http_status(200) expect(json_response['username']).to eq(user.username) - expect(json_response['lfs_token']).to eq(Gitlab::LfsToken.new(key).token) - expect(json_response['repository_http_path']).to eq(project.http_url_to_repo) + expect(Gitlab::LfsToken.new(key).token_valid?(json_response['lfs_token'])).to be_truthy end it 'returns the correct information about the user' do @@ -166,9 +175,8 @@ describe API::Internal do expect(response).to have_gitlab_http_status(200) expect(json_response['username']).to eq(user.username) - expect(json_response['lfs_token']).to eq(Gitlab::LfsToken.new(user).token) - expect(json_response['repository_http_path']).to eq(project.http_url_to_repo) + expect(Gitlab::LfsToken.new(user).token_valid?(json_response['lfs_token'])).to be_truthy end it 'returns a 404 when no key or user is provided' do @@ -198,15 +206,15 @@ describe API::Internal do expect(response).to have_gitlab_http_status(200) expect(json_response['username']).to eq("lfs+deploy-key-#{key.id}") - expect(json_response['lfs_token']).to eq(Gitlab::LfsToken.new(key).token) expect(json_response['repository_http_path']).to eq(project.http_url_to_repo) + expect(Gitlab::LfsToken.new(key).token_valid?(json_response['lfs_token'])).to be_truthy end end end describe "GET /internal/discover" do it "finds a user by key id" do - get(api("/internal/discover"), key_id: key.id, secret_token: secret_token) + get(api("/internal/discover"), params: { key_id: key.id, secret_token: secret_token }) expect(response).to have_gitlab_http_status(200) @@ -214,7 +222,7 @@ describe API::Internal do end it "finds a user by user id" do - get(api("/internal/discover"), user_id: user.id, secret_token: secret_token) + get(api("/internal/discover"), params: { user_id: user.id, secret_token: secret_token }) expect(response).to have_gitlab_http_status(200) @@ -222,7 +230,7 @@ describe API::Internal do end it "finds a user by username" do - get(api("/internal/discover"), username: user.username, secret_token: secret_token) + get(api("/internal/discover"), params: { username: user.username, secret_token: secret_token }) expect(response).to have_gitlab_http_status(200) @@ -233,7 +241,7 @@ describe API::Internal do describe "GET /internal/authorized_keys" do context "using an existing key's fingerprint" do it "finds the key" do - get(api('/internal/authorized_keys'), fingerprint: key.fingerprint, secret_token: secret_token) + get(api('/internal/authorized_keys'), params: { fingerprint: key.fingerprint, secret_token: secret_token }) expect(response.status).to eq(200) expect(json_response["key"]).to eq(key.key) @@ -242,7 +250,7 @@ describe API::Internal do context "non existing key's fingerprint" do it "returns 404" do - get(api('/internal/authorized_keys'), fingerprint: "no:t-:va:li:d0", secret_token: secret_token) + get(api('/internal/authorized_keys'), params: { fingerprint: "no:t-:va:li:d0", secret_token: secret_token }) expect(response.status).to eq(404) end @@ -250,7 +258,7 @@ describe API::Internal do context "using a partial fingerprint" do it "returns 404" do - get(api('/internal/authorized_keys'), fingerprint: "#{key.fingerprint[0..5]}%", secret_token: secret_token) + get(api('/internal/authorized_keys'), params: { fingerprint: "#{key.fingerprint[0..5]}%", secret_token: secret_token }) expect(response.status).to eq(404) end @@ -258,20 +266,20 @@ describe API::Internal do context "sending the key" do it "finds the key" do - get(api('/internal/authorized_keys'), key: key.key.split[1], secret_token: secret_token) + get(api('/internal/authorized_keys'), params: { key: key.key.split[1], secret_token: secret_token }) expect(response.status).to eq(200) expect(json_response["key"]).to eq(key.key) end it "returns 404 with a partial key" do - get(api('/internal/authorized_keys'), key: key.key.split[1][0...-3], secret_token: secret_token) + get(api('/internal/authorized_keys'), params: { key: key.key.split[1][0...-3], secret_token: secret_token }) expect(response.status).to eq(404) end it "returns 404 with an not valid base64 string" do - get(api('/internal/authorized_keys'), key: "whatever!", secret_token: secret_token) + get(api('/internal/authorized_keys'), params: { key: "whatever!", secret_token: secret_token }) expect(response.status).to eq(404) end @@ -679,7 +687,7 @@ describe API::Internal do end it 'returns link to create new merge request' do - get api("/internal/merge_request_urls?project=#{repo_name}&changes=#{changes}"), secret_token: secret_token + get api("/internal/merge_request_urls?project=#{repo_name}&changes=#{changes}"), params: { secret_token: secret_token } expect(json_response).to match [{ "branch_name" => "new_branch", @@ -691,7 +699,7 @@ describe API::Internal do it 'returns empty array if printing_merge_request_link_enabled is false' do project.update!(printing_merge_request_link_enabled: false) - get api("/internal/merge_request_urls?project=#{repo_name}&changes=#{changes}"), secret_token: secret_token + get api("/internal/merge_request_urls?project=#{repo_name}&changes=#{changes}"), params: { secret_token: secret_token } expect(json_response).to eq([]) end @@ -700,7 +708,7 @@ describe API::Internal do let(:gl_repository) { "project-#{project.id}" } it 'returns link to create new merge request' do - get api("/internal/merge_request_urls?gl_repository=#{gl_repository}&changes=#{changes}"), secret_token: secret_token + get api("/internal/merge_request_urls?gl_repository=#{gl_repository}&changes=#{changes}"), params: { secret_token: secret_token } expect(json_response).to match [{ "branch_name" => "new_branch", @@ -819,7 +827,7 @@ describe API::Internal do expect(PostReceive).to receive(:perform_async) .with(gl_repository, identifier, changes) - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params end it 'decreases the reference counter and returns the result' do @@ -827,13 +835,13 @@ describe API::Internal do .and_return(reference_counter) expect(reference_counter).to receive(:decrease).and_return(true) - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params expect(json_response['reference_counter_decreased']).to be(true) end it 'returns link to create new merge request' do - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params expect(json_response['merge_request_urls']).to match [{ "branch_name" => "new_branch", @@ -845,7 +853,7 @@ describe API::Internal do it 'returns empty array if printing_merge_request_link_enabled is false' do project.update!(printing_merge_request_link_enabled: false) - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params expect(json_response['merge_request_urls']).to eq([]) end @@ -854,7 +862,7 @@ describe API::Internal do let!(:broadcast_message) { create(:broadcast_message, starts_at: 1.day.ago, ends_at: 1.day.from_now ) } it 'returns one broadcast message' do - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params expect(response).to have_gitlab_http_status(200) expect(json_response['broadcast_message']).to eq(broadcast_message.message) @@ -863,7 +871,7 @@ describe API::Internal do context 'broadcast message does not exist' do it 'returns empty string' do - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params expect(response).to have_gitlab_http_status(200) expect(json_response['broadcast_message']).to eq(nil) @@ -874,7 +882,7 @@ describe API::Internal do it 'returns empty string' do allow(BroadcastMessage).to receive(:current).and_return(nil) - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params expect(response).to have_gitlab_http_status(200) expect(json_response['broadcast_message']).to eq(nil) @@ -886,7 +894,7 @@ describe API::Internal do project_moved = Gitlab::Checks::ProjectMoved.new(project, user, 'http', 'foo/baz') project_moved.add_message - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params expect(response).to have_gitlab_http_status(200) expect(json_response["redirected_message"]).to be_present @@ -899,7 +907,7 @@ describe API::Internal do project_created = Gitlab::Checks::ProjectCreated.new(project, user, 'http') project_created.add_message - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params expect(response).to have_gitlab_http_status(200) expect(json_response["project_created_message"]).to be_present @@ -911,7 +919,7 @@ describe API::Internal do it 'does not try to notify that project moved' do allow_any_instance_of(Gitlab::Identifier).to receive(:identify).and_return(nil) - post api("/internal/post_receive"), valid_params + post api("/internal/post_receive"), params: valid_params expect(response).to have_gitlab_http_status(200) end @@ -928,7 +936,7 @@ describe API::Internal do .and_return(reference_counter) expect(reference_counter).to receive(:increase).and_return(true) - post api("/internal/pre_receive"), valid_params + post api("/internal/pre_receive"), params: valid_params expect(json_response['reference_counter_increased']).to be(true) end @@ -948,12 +956,14 @@ describe API::Internal do def pull(key, project, protocol = 'ssh') post( api("/internal/allowed"), - key_id: key.id, - project: project.full_path, - gl_repository: gl_repository_for(project), - action: 'git-upload-pack', - secret_token: secret_token, - protocol: protocol + params: { + key_id: key.id, + project: project.full_path, + gl_repository: gl_repository_for(project), + action: 'git-upload-pack', + secret_token: secret_token, + protocol: protocol + } ) end @@ -969,55 +979,56 @@ describe API::Internal do env: env } - if Gitlab.rails5? - post( - api("/internal/allowed"), - params: params - ) - else - post( - api("/internal/allowed"), - params - ) - end + post( + api("/internal/allowed"), + params: params + ) end def archive(key, project) post( api("/internal/allowed"), - ref: 'master', - key_id: key.id, - project: project.full_path, - gl_repository: gl_repository_for(project), - action: 'git-upload-archive', - secret_token: secret_token, - protocol: 'ssh' + params: { + ref: 'master', + key_id: key.id, + project: project.full_path, + gl_repository: gl_repository_for(project), + action: 'git-upload-archive', + secret_token: secret_token, + protocol: 'ssh' + } ) end def lfs_auth_project(project) post( api("/internal/lfs_authenticate"), - secret_token: secret_token, - project: project.full_path + params: { + secret_token: secret_token, + project: project.full_path + } ) end def lfs_auth_key(key_id, project) post( api("/internal/lfs_authenticate"), - key_id: key_id, - secret_token: secret_token, - project: project.full_path + params: { + key_id: key_id, + secret_token: secret_token, + project: project.full_path + } ) end def lfs_auth_user(user_id, project) post( api("/internal/lfs_authenticate"), - user_id: user_id, - secret_token: secret_token, - project: project.full_path + params: { + user_id: user_id, + secret_token: secret_token, + project: project.full_path + } ) end end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index 1827da61e2d..0fd465da4f8 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -66,7 +66,7 @@ describe API::Issues do describe "GET /issues" do context "when unauthenticated" do it "returns an array of all issues" do - get api("/issues"), scope: 'all' + get api("/issues"), params: { scope: 'all' } expect(response).to have_http_status(200) expect(json_response).to be_an Array @@ -79,13 +79,13 @@ describe API::Issues do end it "returns authentication error when scope is assigned-to-me" do - get api("/issues"), scope: 'assigned-to-me' + get api("/issues"), params: { scope: 'assigned-to-me' } expect(response).to have_http_status(401) end it "returns authentication error when scope is created-by-me" do - get api("/issues"), scope: 'created-by-me' + get api("/issues"), params: { scope: 'created-by-me' } expect(response).to have_http_status(401) end @@ -103,21 +103,21 @@ describe API::Issues do end it 'returns an array of closed issues' do - get api('/issues', user), state: :closed + get api('/issues', user), params: { state: :closed } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(closed_issue.id) end it 'returns an array of opened issues' do - get api('/issues', user), state: :opened + get api('/issues', user), params: { state: :opened } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue.id) end it 'returns an array of all issues' do - get api('/issues', user), state: :all + get api('/issues', user), params: { state: :all } expect_paginated_array_response(size: 2) expect(first_issue['id']).to eq(issue.id) @@ -127,7 +127,7 @@ describe API::Issues do it 'returns issues assigned to me' do issue2 = create(:issue, assignees: [user2], project: project) - get api('/issues', user2), scope: 'assigned_to_me' + get api('/issues', user2), params: { scope: 'assigned_to_me' } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id) @@ -136,7 +136,7 @@ describe API::Issues do it 'returns issues assigned to me (kebab-case)' do issue2 = create(:issue, assignees: [user2], project: project) - get api('/issues', user2), scope: 'assigned-to-me' + get api('/issues', user2), params: { scope: 'assigned-to-me' } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id) @@ -145,7 +145,7 @@ describe API::Issues do it 'returns issues authored by the given author id' do issue2 = create(:issue, author: user2, project: project) - get api('/issues', user), author_id: user2.id, scope: 'all' + get api('/issues', user), params: { author_id: user2.id, scope: 'all' } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id) @@ -154,7 +154,7 @@ describe API::Issues do it 'returns issues assigned to the given assignee id' do issue2 = create(:issue, assignees: [user2], project: project) - get api('/issues', user), assignee_id: user2.id, scope: 'all' + get api('/issues', user), params: { assignee_id: user2.id, scope: 'all' } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id) @@ -163,7 +163,7 @@ describe API::Issues do it 'returns issues authored by the given author id and assigned to the given assignee id' do issue2 = create(:issue, author: user2, assignees: [user2], project: project) - get api('/issues', user), author_id: user2.id, assignee_id: user2.id, scope: 'all' + get api('/issues', user), params: { author_id: user2.id, assignee_id: user2.id, scope: 'all' } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id) @@ -172,7 +172,7 @@ describe API::Issues do it 'returns issues with no assignee' do issue2 = create(:issue, author: user2, project: project) - get api('/issues', user), assignee_id: 0, scope: 'all' + get api('/issues', user), params: { assignee_id: 0, scope: 'all' } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id) @@ -181,7 +181,7 @@ describe API::Issues do it 'returns issues with no assignee' do issue2 = create(:issue, author: user2, project: project) - get api('/issues', user), assignee_id: 'None', scope: 'all' + get api('/issues', user), params: { assignee_id: 'None', scope: 'all' } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id) @@ -191,7 +191,7 @@ describe API::Issues do # This issue without assignee should not be returned create(:issue, author: user2, project: project) - get api('/issues', user), assignee_id: 'Any', scope: 'all' + get api('/issues', user), params: { assignee_id: 'Any', scope: 'all' } expect_paginated_array_response(size: 3) end @@ -202,7 +202,7 @@ describe API::Issues do create(:award_emoji, awardable: issue, user: user2, name: 'thumbsup') - get api('/issues', user2), my_reaction_emoji: 'Any', scope: 'all' + get api('/issues', user2), params: { my_reaction_emoji: 'Any', scope: 'all' } expect_paginated_array_response(size: 2) end @@ -211,20 +211,20 @@ describe API::Issues do issue2 = create(:issue, project: project, author: user, assignees: [user]) create(:award_emoji, awardable: issue2, user: user2, name: 'star') - get api('/issues', user2), my_reaction_emoji: 'None', scope: 'all' + get api('/issues', user2), params: { my_reaction_emoji: 'None', scope: 'all' } expect_paginated_array_response(size: 2) end it 'returns issues matching given search string for title' do - get api("/issues", user), search: issue.title + get api("/issues", user), params: { search: issue.title } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(issue.id) end it 'returns issues matching given search string for description' do - get api("/issues", user), search: issue.description + get api("/issues", user), params: { search: issue.description } expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue.id) @@ -267,7 +267,7 @@ describe API::Issues do end it 'returns an array of labeled issues' do - get api("/issues", user), labels: label.title + get api("/issues", user), params: { labels: label.title } expect_paginated_array_response(size: 1) expect(first_issue['labels']).to eq([label.title]) @@ -280,20 +280,20 @@ describe API::Issues do create(:label_link, label: label_b, target: issue) create(:label_link, label: label_c, target: issue) - get api("/issues", user), labels: "#{label.title},#{label_b.title},#{label_c.title}" + get api("/issues", user), params: { labels: "#{label.title},#{label_b.title},#{label_c.title}" } expect_paginated_array_response(size: 1) expect(json_response.first['labels']).to eq([label_c.title, label_b.title, label.title]) end it 'returns an empty array if no issue matches labels' do - get api('/issues', user), labels: 'foo,bar' + get api('/issues', user), params: { labels: 'foo,bar' } expect_paginated_array_response(size: 0) end it 'returns an array of labeled issues matching given state' do - get api("/issues", user), labels: label.title, state: :opened + get api("/issues", user), params: { labels: label.title, state: :opened } expect_paginated_array_response(size: 1) expect(json_response.first['labels']).to eq([label.title]) @@ -301,27 +301,27 @@ describe API::Issues do end it 'returns an empty array if no issue matches labels and state filters' do - get api("/issues", user), labels: label.title, state: :closed + get api("/issues", user), params: { labels: label.title, state: :closed } expect_paginated_array_response(size: 0) end it 'returns an array of issues with any label' do - get api("/issues", user), labels: IssuesFinder::FILTER_ANY + get api("/issues", user), params: { labels: IssuesFinder::FILTER_ANY } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(issue.id) end it 'returns an array of issues with no label' do - get api("/issues", user), labels: IssuesFinder::FILTER_NONE + get api("/issues", user), params: { labels: IssuesFinder::FILTER_NONE } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(closed_issue.id) end it 'returns an array of issues with no label when using the legacy No+Label filter' do - get api("/issues", user), labels: "No Label" + get api("/issues", user), params: { labels: "No Label" } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(closed_issue.id) @@ -363,14 +363,14 @@ describe API::Issues do end it 'returns an array of issues found by iids' do - get api('/issues', user), iids: [closed_issue.iid] + get api('/issues', user), params: { iids: [closed_issue.iid] } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(closed_issue.id) end it 'returns an empty array if iid does not exist' do - get api("/issues", user), iids: [99999] + get api("/issues", user), params: { iids: [99999] } expect_paginated_array_response(size: 0) end @@ -506,58 +506,58 @@ describe API::Issues do end it 'returns group issues without confidential issues for non project members' do - get api(base_url, non_member), state: :opened + get api(base_url, non_member), params: { state: :opened } expect_paginated_array_response(size: 1) expect(json_response.first['title']).to eq(group_issue.title) end it 'returns group confidential issues for author' do - get api(base_url, author), state: :opened + get api(base_url, author), params: { state: :opened } expect_paginated_array_response(size: 2) end it 'returns group confidential issues for assignee' do - get api(base_url, assignee), state: :opened + get api(base_url, assignee), params: { state: :opened } expect_paginated_array_response(size: 2) end it 'returns group issues with confidential issues for project members' do - get api(base_url, user), state: :opened + get api(base_url, user), params: { state: :opened } expect_paginated_array_response(size: 2) end it 'returns group confidential issues for admin' do - get api(base_url, admin), state: :opened + get api(base_url, admin), params: { state: :opened } expect_paginated_array_response(size: 2) end it 'returns an array of labeled group issues' do - get api(base_url, user), labels: group_label.title + get api(base_url, user), params: { labels: group_label.title } expect_paginated_array_response(size: 1) expect(json_response.first['labels']).to eq([group_label.title]) end it 'returns an array of labeled group issues where all labels match' do - get api(base_url, user), labels: "#{group_label.title},foo,bar" + get api(base_url, user), params: { labels: "#{group_label.title},foo,bar" } expect_paginated_array_response(size: 0) end it 'returns issues matching given search string for title' do - get api(base_url, user), search: group_issue.title + get api(base_url, user), params: { search: group_issue.title } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_issue.id) end it 'returns issues matching given search string for description' do - get api(base_url, user), search: group_issue.description + get api(base_url, user), params: { search: group_issue.description } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_issue.id) @@ -570,40 +570,40 @@ describe API::Issues do create(:label_link, label: label_b, target: group_issue) create(:label_link, label: label_c, target: group_issue) - get api(base_url, user), labels: "#{group_label.title},#{label_b.title},#{label_c.title}" + get api(base_url, user), params: { labels: "#{group_label.title},#{label_b.title},#{label_c.title}" } expect_paginated_array_response(size: 1) expect(json_response.first['labels']).to eq([label_c.title, label_b.title, group_label.title]) end it 'returns an array of issues found by iids' do - get api(base_url, user), iids: [group_issue.iid] + get api(base_url, user), params: { iids: [group_issue.iid] } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_issue.id) end it 'returns an empty array if iid does not exist' do - get api(base_url, user), iids: [99999] + get api(base_url, user), params: { iids: [99999] } expect_paginated_array_response(size: 0) end it 'returns an empty array if no group issue matches labels' do - get api(base_url, user), labels: 'foo,bar' + get api(base_url, user), params: { labels: 'foo,bar' } expect_paginated_array_response(size: 0) end it 'returns an array of group issues with any label' do - get api(base_url, user), labels: IssuesFinder::FILTER_ANY + get api(base_url, user), params: { labels: IssuesFinder::FILTER_ANY } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_issue.id) end it 'returns an array of group issues with no label' do - get api(base_url, user), labels: IssuesFinder::FILTER_NONE + get api(base_url, user), params: { labels: IssuesFinder::FILTER_NONE } response_ids = json_response.map { |issue| issue['id'] } @@ -612,33 +612,33 @@ describe API::Issues do end it 'returns an empty array if no issue matches milestone' do - get api(base_url, user), milestone: group_empty_milestone.title + get api(base_url, user), params: { milestone: group_empty_milestone.title } expect_paginated_array_response(size: 0) end it 'returns an empty array if milestone does not exist' do - get api(base_url, user), milestone: 'foo' + get api(base_url, user), params: { milestone: 'foo' } expect_paginated_array_response(size: 0) end it 'returns an array of issues in given milestone' do - get api(base_url, user), state: :opened, milestone: group_milestone.title + get api(base_url, user), params: { state: :opened, milestone: group_milestone.title } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_issue.id) end it 'returns an array of issues matching state in milestone' do - get api(base_url, user), milestone: group_milestone.title, state: :closed + get api(base_url, user), params: { milestone: group_milestone.title, state: :closed } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_closed_issue.id) end it 'returns an array of issues with no milestone' do - get api(base_url, user), milestone: no_milestone_title + get api(base_url, user), params: { milestone: no_milestone_title } expect(response).to have_gitlab_http_status(200) @@ -674,7 +674,7 @@ describe API::Issues do end it 'sorts by updated_at ascending when requested' do - get api(base_url, user), order_by: :updated_at, sort: :asc + get api(base_url, user), params: { order_by: :updated_at, sort: :asc } response_dates = json_response.map { |issue| issue['updated_at'] } @@ -777,7 +777,7 @@ describe API::Issues do end it 'returns an array of labeled project issues' do - get api("#{base_url}/issues", user), labels: label.title + get api("#{base_url}/issues", user), params: { labels: label.title } expect_paginated_array_response(size: 1) expect(json_response.first['labels']).to eq([label.title]) @@ -790,7 +790,7 @@ describe API::Issues do create(:label_link, label: label_b, target: issue) create(:label_link, label: label_c, target: issue) - get api("#{base_url}/issues", user), labels: "#{label.title},#{label_b.title},#{label_c.title}" + get api("#{base_url}/issues", user), params: { labels: "#{label.title},#{label_b.title},#{label_c.title}" } expect_paginated_array_response(size: 1) expect(json_response.first['labels']).to eq([label_c.title, label_b.title, label.title]) @@ -811,14 +811,14 @@ describe API::Issues do end it 'returns an array of issues found by iids' do - get api("#{base_url}/issues", user), iids: [issue.iid] + get api("#{base_url}/issues", user), params: { iids: [issue.iid] } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(issue.id) end it 'returns an empty array if iid does not exist' do - get api("#{base_url}/issues", user), iids: [99999] + get api("#{base_url}/issues", user), params: { iids: [99999] } expect_paginated_array_response(size: 0) end @@ -830,14 +830,14 @@ describe API::Issues do end it 'returns an array of project issues with any label' do - get api("#{base_url}/issues", user), labels: IssuesFinder::FILTER_ANY + get api("#{base_url}/issues", user), params: { labels: IssuesFinder::FILTER_ANY } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(issue.id) end it 'returns an array of project issues with no label' do - get api("#{base_url}/issues", user), labels: IssuesFinder::FILTER_NONE + get api("#{base_url}/issues", user), params: { labels: IssuesFinder::FILTER_NONE } response_ids = json_response.map { |issue| issue['id'] } @@ -846,25 +846,25 @@ describe API::Issues do end it 'returns an empty array if no project issue matches labels' do - get api("#{base_url}/issues", user), labels: 'foo,bar' + get api("#{base_url}/issues", user), params: { labels: 'foo,bar' } expect_paginated_array_response(size: 0) end it 'returns an empty array if no issue matches milestone' do - get api("#{base_url}/issues", user), milestone: empty_milestone.title + get api("#{base_url}/issues", user), params: { milestone: empty_milestone.title } expect_paginated_array_response(size: 0) end it 'returns an empty array if milestone does not exist' do - get api("#{base_url}/issues", user), milestone: :foo + get api("#{base_url}/issues", user), params: { milestone: :foo } expect_paginated_array_response(size: 0) end it 'returns an array of issues in given milestone' do - get api("#{base_url}/issues", user), milestone: milestone.title + get api("#{base_url}/issues", user), params: { milestone: milestone.title } expect_paginated_array_response(size: 2) expect(json_response.first['id']).to eq(issue.id) @@ -872,21 +872,21 @@ describe API::Issues do end it 'returns an array of issues matching state in milestone' do - get api("#{base_url}/issues", user), milestone: milestone.title, state: :closed + get api("#{base_url}/issues", user), params: { milestone: milestone.title, state: :closed } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(closed_issue.id) end it 'returns an array of issues with no milestone' do - get api("#{base_url}/issues", user), milestone: no_milestone_title + get api("#{base_url}/issues", user), params: { milestone: no_milestone_title } expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(confidential_issue.id) end it 'returns an array of issues with any milestone' do - get api("#{base_url}/issues", user), milestone: any_milestone_title + get api("#{base_url}/issues", user), params: { milestone: any_milestone_title } response_ids = json_response.map { |issue| issue['id'] } @@ -904,7 +904,7 @@ describe API::Issues do end it 'sorts ascending when requested' do - get api("#{base_url}/issues", user), sort: :asc + get api("#{base_url}/issues", user), params: { sort: :asc } response_dates = json_response.map { |issue| issue['created_at'] } @@ -913,7 +913,7 @@ describe API::Issues do end it 'sorts by updated_at descending when requested' do - get api("#{base_url}/issues", user), order_by: :updated_at + get api("#{base_url}/issues", user), params: { order_by: :updated_at } response_dates = json_response.map { |issue| issue['updated_at'] } @@ -922,7 +922,7 @@ describe API::Issues do end it 'sorts by updated_at ascending when requested' do - get api("#{base_url}/issues", user), order_by: :updated_at, sort: :asc + get api("#{base_url}/issues", user), params: { order_by: :updated_at, sort: :asc } response_dates = json_response.map { |issue| issue['updated_at'] } @@ -1051,7 +1051,7 @@ describe API::Issues do context 'support for deprecated assignee_id' do it 'creates a new project issue' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', assignee_id: user2.id + params: { title: 'new issue', assignee_id: user2.id } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('new issue') @@ -1061,7 +1061,7 @@ describe API::Issues do it 'creates a new project issue when assignee_id is empty' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', assignee_id: '' + params: { title: 'new issue', assignee_id: '' } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('new issue') @@ -1072,7 +1072,7 @@ describe API::Issues do context 'single assignee restrictions' do it 'creates a new project issue with no more than one assignee' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', assignee_ids: [user2.id, guest.id] + params: { title: 'new issue', assignee_ids: [user2.id, guest.id] } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('new issue') @@ -1088,7 +1088,7 @@ describe API::Issues do end it 'renders 403' do - post api("/projects/#{project.id}/issues", not_member), title: 'new issue' + post api("/projects/#{project.id}/issues", not_member), params: { title: 'new issue' } expect(response).to have_gitlab_http_status(403) end @@ -1098,7 +1098,7 @@ describe API::Issues do context 'by an admin' do it 'sets the internal ID on the new issue' do post api("/projects/#{project.id}/issues", admin), - title: 'new issue', iid: 9001 + params: { title: 'new issue', iid: 9001 } expect(response).to have_gitlab_http_status(201) expect(json_response['iid']).to eq 9001 @@ -1108,7 +1108,7 @@ describe API::Issues do context 'by an owner' do it 'sets the internal ID on the new issue' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', iid: 9001 + params: { title: 'new issue', iid: 9001 } expect(response).to have_gitlab_http_status(201) expect(json_response['iid']).to eq 9001 @@ -1122,7 +1122,7 @@ describe API::Issues do it 'sets the internal ID on the new issue' do group.add_owner(user2) post api("/projects/#{group_project.id}/issues", user2), - title: 'new issue', iid: 9001 + params: { title: 'new issue', iid: 9001 } expect(response).to have_gitlab_http_status(201) expect(json_response['iid']).to eq 9001 @@ -1132,7 +1132,7 @@ describe API::Issues do context 'by another user' do it 'ignores the given internal ID' do post api("/projects/#{project.id}/issues", user2), - title: 'new issue', iid: 9001 + params: { title: 'new issue', iid: 9001 } expect(response).to have_gitlab_http_status(201) expect(json_response['iid']).not_to eq 9001 @@ -1142,8 +1142,7 @@ describe API::Issues do it 'creates a new project issue' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', labels: 'label, label2', weight: 3, - assignee_ids: [user2.id] + params: { title: 'new issue', labels: 'label, label2', weight: 3, assignee_ids: [user2.id] } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('new issue') @@ -1156,7 +1155,7 @@ describe API::Issues do it 'creates a new confidential project issue' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', confidential: true + params: { title: 'new issue', confidential: true } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('new issue') @@ -1165,7 +1164,7 @@ describe API::Issues do it 'creates a new confidential project issue with a different param' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', confidential: 'y' + params: { title: 'new issue', confidential: 'y' } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('new issue') @@ -1174,7 +1173,7 @@ describe API::Issues do it 'creates a public issue when confidential param is false' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', confidential: false + params: { title: 'new issue', confidential: false } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('new issue') @@ -1183,21 +1182,23 @@ describe API::Issues do it 'creates a public issue when confidential param is invalid' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', confidential: 'foo' + params: { title: 'new issue', confidential: 'foo' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('confidential is invalid') end it "returns a 400 bad request if title not given" do - post api("/projects/#{project.id}/issues", user), labels: 'label, label2' + post api("/projects/#{project.id}/issues", user), params: { labels: 'label, label2' } expect(response).to have_gitlab_http_status(400) end it 'allows special label names' do post api("/projects/#{project.id}/issues", user), - title: 'new issue', - labels: 'label, label?, label&foo, ?, &' + params: { + title: 'new issue', + labels: 'label, label?, label&foo, ?, &' + } expect(response.status).to eq(201) expect(json_response['labels']).to include 'label' expect(json_response['labels']).to include 'label?' @@ -1208,7 +1209,7 @@ describe API::Issues do it 'returns 400 if title is too long' do post api("/projects/#{project.id}/issues", user), - title: 'g' * 256 + params: { title: 'g' * 256 } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['title']).to eq([ 'is too long (maximum is 255 characters)' @@ -1227,8 +1228,10 @@ describe API::Issues do context 'resolving all discussions in a merge request' do before do post api("/projects/#{project.id}/issues", user), - title: 'New Issue', - merge_request_to_resolve_discussions_of: merge_request.iid + params: { + title: 'New Issue', + merge_request_to_resolve_discussions_of: merge_request.iid + } end it_behaves_like 'creating an issue resolving discussions through the API' @@ -1237,9 +1240,11 @@ describe API::Issues do context 'resolving a single discussion' do before do post api("/projects/#{project.id}/issues", user), - title: 'New Issue', - merge_request_to_resolve_discussions_of: merge_request.iid, - discussion_to_resolve: discussion.id + params: { + title: 'New Issue', + merge_request_to_resolve_discussions_of: merge_request.iid, + discussion_to_resolve: discussion.id + } end it_behaves_like 'creating an issue resolving discussions through the API' @@ -1251,7 +1256,7 @@ describe API::Issues do due_date = 2.weeks.from_now.strftime('%Y-%m-%d') post api("/projects/#{project.id}/issues", user), - title: 'new issue', due_date: due_date + params: { title: 'new issue', due_date: due_date } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('new issue') @@ -1266,7 +1271,7 @@ describe API::Issues do context 'by an admin' do it 'sets the creation time on the new issue' do - post api("/projects/#{project.id}/issues", admin), params + post api("/projects/#{project.id}/issues", admin), params: params expect(response).to have_gitlab_http_status(201) expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) @@ -1275,7 +1280,7 @@ describe API::Issues do context 'by a project owner' do it 'sets the creation time on the new issue' do - post api("/projects/#{project.id}/issues", user), params + post api("/projects/#{project.id}/issues", user), params: params expect(response).to have_gitlab_http_status(201) expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) @@ -1287,7 +1292,7 @@ describe API::Issues do group = create(:group) group_project = create(:project, :public, namespace: group) group.add_owner(user2) - post api("/projects/#{group_project.id}/issues", user2), params + post api("/projects/#{group_project.id}/issues", user2), params: params expect(response).to have_gitlab_http_status(201) expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) @@ -1296,7 +1301,7 @@ describe API::Issues do context 'by another user' do it 'ignores the given creation time' do - post api("/projects/#{project.id}/issues", user2), params + post api("/projects/#{project.id}/issues", user2), params: params expect(response).to have_gitlab_http_status(201) expect(Time.parse(json_response['created_at'])).not_to be_like_time(creation_time) @@ -1307,7 +1312,7 @@ describe API::Issues do context 'the user can only read the issue' do it 'cannot create new labels' do expect do - post api("/projects/#{project.id}/issues", non_member), title: 'new issue', labels: 'label, label2' + post api("/projects/#{project.id}/issues", non_member), params: { title: 'new issue', labels: 'label, label2' } end.not_to change { project.labels.count } end end @@ -1328,7 +1333,7 @@ describe API::Issues do end it "does not create a new project issue" do - expect { post api("/projects/#{project.id}/issues", user), params }.not_to change(Issue, :count) + expect { post api("/projects/#{project.id}/issues", user), params: params }.not_to change(Issue, :count) expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) @@ -1344,7 +1349,7 @@ describe API::Issues do describe "PUT /projects/:id/issues/:issue_iid to update only title" do it "updates a project issue" do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - title: 'updated title' + params: { title: 'updated title' } expect(response).to have_gitlab_http_status(200) expect(json_response['title']).to eq('updated title') @@ -1352,20 +1357,22 @@ describe API::Issues do it "returns 404 error if issue iid not found" do put api("/projects/#{project.id}/issues/44444", user), - title: 'updated title' + params: { title: 'updated title' } expect(response).to have_gitlab_http_status(404) end it "returns 404 error if issue id is used instead of the iid" do put api("/projects/#{project.id}/issues/#{issue.id}", user), - title: 'updated title' + params: { title: 'updated title' } expect(response).to have_gitlab_http_status(404) end it 'allows special label names' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - title: 'updated title', - labels: 'label, label?, label&foo, ?, &' + params: { + title: 'updated title', + labels: 'label, label?, label&foo, ?, &' + } expect(response.status).to eq(200) expect(json_response['labels']).to include 'label' @@ -1378,40 +1385,40 @@ describe API::Issues do context 'confidential issues' do it "returns 403 for non project members" do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", non_member), - title: 'updated title' + params: { title: 'updated title' } expect(response).to have_gitlab_http_status(403) end it "returns 403 for project members with guest role" do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", guest), - title: 'updated title' + params: { title: 'updated title' } expect(response).to have_gitlab_http_status(403) end it "updates a confidential issue for project members" do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user), - title: 'updated title' + params: { title: 'updated title' } expect(response).to have_gitlab_http_status(200) expect(json_response['title']).to eq('updated title') end it "updates a confidential issue for author" do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", author), - title: 'updated title' + params: { title: 'updated title' } expect(response).to have_gitlab_http_status(200) expect(json_response['title']).to eq('updated title') end it "updates a confidential issue for admin" do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", admin), - title: 'updated title' + params: { title: 'updated title' } expect(response).to have_gitlab_http_status(200) expect(json_response['title']).to eq('updated title') end it 'sets an issue to confidential' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - confidential: true + params: { confidential: true } expect(response).to have_gitlab_http_status(200) expect(json_response['confidential']).to be_truthy @@ -1419,7 +1426,7 @@ describe API::Issues do it 'makes a confidential issue public' do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user), - confidential: false + params: { confidential: false } expect(response).to have_gitlab_http_status(200) expect(json_response['confidential']).to be_falsy @@ -1427,7 +1434,7 @@ describe API::Issues do it 'does not update a confidential issue with wrong confidential flag' do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user), - confidential: 'foo' + params: { confidential: 'foo' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('confidential is invalid') @@ -1448,7 +1455,7 @@ describe API::Issues do allow_any_instance_of(SpamService).to receive_messages(check_for_spam?: true) allow_any_instance_of(AkismetService).to receive_messages(spam?: true) - put api("/projects/#{project.id}/issues/#{issue.iid}", user), params + put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: params expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) @@ -1466,7 +1473,7 @@ describe API::Issues do context 'support for deprecated assignee_id' do it 'removes assignee' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - assignee_id: 0 + params: { assignee_id: 0 } expect(response).to have_gitlab_http_status(200) @@ -1475,7 +1482,7 @@ describe API::Issues do it 'updates an issue with new assignee' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - assignee_id: user2.id + params: { assignee_id: user2.id } expect(response).to have_gitlab_http_status(200) @@ -1485,7 +1492,7 @@ describe API::Issues do it 'removes assignee' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - assignee_ids: [0] + params: { assignee_ids: [0] } expect(response).to have_gitlab_http_status(200) @@ -1494,7 +1501,7 @@ describe API::Issues do it 'updates an issue with new assignee' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - assignee_ids: [user2.id] + params: { assignee_ids: [user2.id] } expect(response).to have_gitlab_http_status(200) @@ -1504,7 +1511,7 @@ describe API::Issues do context 'single assignee restrictions' do it 'updates an issue with several assignees but only one has been applied' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - assignee_ids: [user2.id, guest.id] + params: { assignee_ids: [user2.id, guest.id] } expect(response).to have_gitlab_http_status(200) @@ -1519,14 +1526,14 @@ describe API::Issues do it 'does not update labels if not present' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - title: 'updated title' + params: { title: 'updated title' } expect(response).to have_gitlab_http_status(200) expect(json_response['labels']).to eq([label.title]) end it 'removes all labels and touches the record' do Timecop.travel(1.minute.from_now) do - put api("/projects/#{project.id}/issues/#{issue.iid}", user), labels: '' + put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: '' } end expect(response).to have_gitlab_http_status(200) @@ -1537,7 +1544,7 @@ describe API::Issues do it 'updates labels and touches the record' do Timecop.travel(1.minute.from_now) do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - labels: 'foo,bar' + params: { labels: 'foo,bar' } end expect(response).to have_gitlab_http_status(200) expect(json_response['labels']).to include 'foo' @@ -1547,7 +1554,7 @@ describe API::Issues do it 'allows special label names' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - labels: 'label:foo, label-bar,label_bar,label/bar,label?bar,label&bar,?,&' + params: { labels: 'label:foo, label-bar,label_bar,label/bar,label?bar,label&bar,?,&' } expect(response.status).to eq(200) expect(json_response['labels']).to include 'label:foo' expect(json_response['labels']).to include 'label-bar' @@ -1561,7 +1568,7 @@ describe API::Issues do it 'returns 400 if title is too long' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - title: 'g' * 256 + params: { title: 'g' * 256 } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['title']).to eq([ 'is too long (maximum is 255 characters)' @@ -1572,7 +1579,7 @@ describe API::Issues do describe "PUT /projects/:id/issues/:issue_iid to update state and label" do it "updates a project issue" do put api("/projects/#{project.id}/issues/#{issue.iid}", user), - labels: 'label2', state_event: "close" + params: { labels: 'label2', state_event: "close" } expect(response).to have_gitlab_http_status(200) expect(json_response['labels']).to include 'label2' @@ -1580,7 +1587,7 @@ describe API::Issues do end it 'reopens a project isssue' do - put api("/projects/#{project.id}/issues/#{closed_issue.iid}", user), state_event: 'reopen' + put api("/projects/#{project.id}/issues/#{closed_issue.iid}", user), params: { state_event: 'reopen' } expect(response).to have_gitlab_http_status(200) expect(json_response['state']).to eq 'opened' @@ -1590,7 +1597,7 @@ describe API::Issues do it 'accepts the update date to be set' do update_time = 2.weeks.ago put api("/projects/#{project.id}/issues/#{issue.iid}", user), - labels: 'label3', state_event: 'close', updated_at: update_time + params: { labels: 'label3', state_event: 'close', updated_at: update_time } expect(response).to have_gitlab_http_status(200) expect(json_response['labels']).to include 'label3' @@ -1603,7 +1610,7 @@ describe API::Issues do it 'creates a new project issue' do due_date = 2.weeks.from_now.strftime('%Y-%m-%d') - put api("/projects/#{project.id}/issues/#{issue.iid}", user), due_date: due_date + put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { due_date: due_date } expect(response).to have_gitlab_http_status(200) expect(json_response['due_date']).to eq(due_date) @@ -1657,7 +1664,7 @@ describe API::Issues do it 'moves an issue' do post api("/projects/#{project.id}/issues/#{issue.iid}/move", user), - to_project_id: target_project.id + params: { to_project_id: target_project.id } expect(response).to have_gitlab_http_status(201) expect(json_response['project_id']).to eq(target_project.id) @@ -1666,7 +1673,7 @@ describe API::Issues do context 'when source and target projects are the same' do it 'returns 400 when trying to move an issue' do post api("/projects/#{project.id}/issues/#{issue.iid}/move", user), - to_project_id: project.id + params: { to_project_id: project.id } expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('Cannot move issue to project it originates from!') @@ -1676,7 +1683,7 @@ describe API::Issues do context 'when the user does not have the permission to move issues' do it 'returns 400 when trying to move an issue' do post api("/projects/#{project.id}/issues/#{issue.iid}/move", user), - to_project_id: target_project2.id + params: { to_project_id: target_project2.id } expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('Cannot move issue due to insufficient permissions!') @@ -1685,7 +1692,7 @@ describe API::Issues do it 'moves the issue to another namespace if I am admin' do post api("/projects/#{project.id}/issues/#{issue.iid}/move", admin), - to_project_id: target_project2.id + params: { to_project_id: target_project2.id } expect(response).to have_gitlab_http_status(201) expect(json_response['project_id']).to eq(target_project2.id) @@ -1694,7 +1701,7 @@ describe API::Issues do context 'when using the issue ID instead of iid' do it 'returns 404 when trying to move an issue' do post api("/projects/#{project.id}/issues/#{issue.id}/move", user), - to_project_id: target_project.id + params: { to_project_id: target_project.id } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Issue Not Found') @@ -1704,7 +1711,7 @@ describe API::Issues do context 'when issue does not exist' do it 'returns 404 when trying to move an issue' do post api("/projects/#{project.id}/issues/123/move", user), - to_project_id: target_project.id + params: { to_project_id: target_project.id } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Issue Not Found') @@ -1714,7 +1721,7 @@ describe API::Issues do context 'when source project does not exist' do it 'returns 404 when trying to move an issue' do post api("/projects/0/issues/#{issue.iid}/move", user), - to_project_id: target_project.id + params: { to_project_id: target_project.id } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Project Not Found') @@ -1724,7 +1731,7 @@ describe API::Issues do context 'when target project does not exist' do it 'returns 404 when trying to move an issue' do post api("/projects/#{project.id}/issues/#{issue.iid}/move", user), - to_project_id: 0 + params: { to_project_id: 0 } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb index cd4e480ca64..97aa71bf231 100644 --- a/spec/requests/api/jobs_spec.rb +++ b/spec/requests/api/jobs_spec.rb @@ -58,7 +58,7 @@ describe API::Jobs do before do |example| unless example.metadata[:skip_before_request] - get api("/projects/#{project.id}/jobs", api_user), query + get api("/projects/#{project.id}/jobs", api_user), params: query end end @@ -142,15 +142,25 @@ describe API::Jobs do end context 'unauthorized user' do - let(:api_user) { nil } + context 'when user is not logged in' do + let(:api_user) { nil } - it 'does not return project jobs' do - expect(response).to have_gitlab_http_status(401) + it 'does not return project jobs' do + expect(response).to have_gitlab_http_status(401) + end + end + + context 'when user is guest' do + let(:api_user) { guest } + + it 'does not return project jobs' do + expect(response).to have_gitlab_http_status(403) + end end end def go - get api("/projects/#{project.id}/jobs", api_user), query + get api("/projects/#{project.id}/jobs", api_user), params: query end end @@ -160,7 +170,7 @@ describe API::Jobs do before do |example| unless example.metadata[:skip_before_request] job - get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), query + get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), params: query end end @@ -229,22 +239,32 @@ describe API::Jobs do it 'avoids N+1 queries' do control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do - get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), query + get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), params: query end.count 3.times { create(:ci_build, :trace_artifact, :artifacts, :test_reports, pipeline: pipeline) } expect do - get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), query + get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), params: query end.not_to exceed_all_query_limit(control_count) end end context 'unauthorized user' do - let(:api_user) { nil } + context 'when user is not logged in' do + let(:api_user) { nil } - it 'does not return jobs' do - expect(response).to have_gitlab_http_status(401) + it 'does not return jobs' do + expect(response).to have_gitlab_http_status(401) + end + end + + context 'when user is guest' do + let(:api_user) { guest } + + it 'does not return jobs' do + expect(response).to have_gitlab_http_status(403) + end end end end @@ -479,7 +499,7 @@ describe API::Jobs do end def get_for_ref(ref = pipeline.ref, job_name = job.name) - get api("/projects/#{project.id}/jobs/artifacts/#{ref}/download", api_user), job: job_name + get api("/projects/#{project.id}/jobs/artifacts/#{ref}/download", api_user), params: { job: job_name } end context 'when not logged in' do @@ -712,7 +732,7 @@ describe API::Jobs do end def get_artifact_file(artifact_path, ref = pipeline.ref, job_name = job.name) - get api("/projects/#{project.id}/jobs/artifacts/#{ref}/raw/#{artifact_path}", api_user), job: job_name + get api("/projects/#{project.id}/jobs/artifacts/#{ref}/raw/#{artifact_path}", api_user), params: { job: job_name } end end diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb index b8a4a04a7e4..49eea2e362b 100644 --- a/spec/requests/api/labels_spec.rb +++ b/spec/requests/api/labels_spec.rb @@ -70,10 +70,12 @@ describe API::Labels do describe 'POST /projects/:id/labels' do it 'returns created label when all params' do post api("/projects/#{project.id}/labels", user), - name: 'Foo', - color: '#FFAABB', - description: 'test', - priority: 2 + params: { + name: 'Foo', + color: '#FFAABB', + description: 'test', + priority: 2 + } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq('Foo') @@ -84,8 +86,10 @@ describe API::Labels do it 'returns created label when only required params' do post api("/projects/#{project.id}/labels", user), - name: 'Foo & Bar', - color: '#FFAABB' + params: { + name: 'Foo & Bar', + color: '#FFAABB' + } expect(response.status).to eq(201) expect(json_response['name']).to eq('Foo & Bar') @@ -96,9 +100,11 @@ describe API::Labels do it 'creates a prioritized label' do post api("/projects/#{project.id}/labels", user), - name: 'Foo & Bar', - color: '#FFAABB', - priority: 3 + params: { + name: 'Foo & Bar', + color: '#FFAABB', + priority: 3 + } expect(response.status).to eq(201) expect(json_response['name']).to eq('Foo & Bar') @@ -108,35 +114,41 @@ describe API::Labels do end it 'returns a 400 bad request if name not given' do - post api("/projects/#{project.id}/labels", user), color: '#FFAABB' + post api("/projects/#{project.id}/labels", user), params: { color: '#FFAABB' } expect(response).to have_gitlab_http_status(400) end it 'returns a 400 bad request if color not given' do - post api("/projects/#{project.id}/labels", user), name: 'Foobar' + post api("/projects/#{project.id}/labels", user), params: { name: 'Foobar' } expect(response).to have_gitlab_http_status(400) end it 'returns 400 for invalid color' do post api("/projects/#{project.id}/labels", user), - name: 'Foo', - color: '#FFAA' + params: { + name: 'Foo', + color: '#FFAA' + } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['color']).to eq(['must be a valid color code']) end it 'returns 400 for too long color code' do post api("/projects/#{project.id}/labels", user), - name: 'Foo', - color: '#FFAAFFFF' + params: { + name: 'Foo', + color: '#FFAAFFFF' + } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['color']).to eq(['must be a valid color code']) end it 'returns 400 for invalid name' do post api("/projects/#{project.id}/labels", user), - name: ',', - color: '#FFAABB' + params: { + name: ',', + color: '#FFAABB' + } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['title']).to eq(['is invalid']) end @@ -147,8 +159,10 @@ describe API::Labels do project.update(group: group) post api("/projects/#{project.id}/labels", user), - name: group_label.name, - color: '#FFAABB' + params: { + name: group_label.name, + color: '#FFAABB' + } expect(response).to have_gitlab_http_status(409) expect(json_response['message']).to eq('Label already exists') @@ -156,17 +170,21 @@ describe API::Labels do it 'returns 400 for invalid priority' do post api("/projects/#{project.id}/labels", user), - name: 'Foo', - color: '#FFAAFFFF', - priority: 'foo' + params: { + name: 'Foo', + color: '#FFAAFFFF', + priority: 'foo' + } expect(response).to have_gitlab_http_status(400) end it 'returns 409 if label already exists in project' do post api("/projects/#{project.id}/labels", user), - name: 'label1', - color: '#FFAABB' + params: { + name: 'label1', + color: '#FFAABB' + } expect(response).to have_gitlab_http_status(409) expect(json_response['message']).to eq('Label already exists') end @@ -174,13 +192,13 @@ describe API::Labels do describe 'DELETE /projects/:id/labels' do it 'returns 204 for existing label' do - delete api("/projects/#{project.id}/labels", user), name: 'label1' + delete api("/projects/#{project.id}/labels", user), params: { name: 'label1' } expect(response).to have_gitlab_http_status(204) end it 'returns 404 for non existing label' do - delete api("/projects/#{project.id}/labels", user), name: 'label2' + delete api("/projects/#{project.id}/labels", user), params: { name: 'label2' } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Label Not Found') end @@ -199,10 +217,12 @@ describe API::Labels do describe 'PUT /projects/:id/labels' do it 'returns 200 if name and colors and description are changed' do put api("/projects/#{project.id}/labels", user), - name: 'label1', - new_name: 'New Label', - color: '#FFFFFF', - description: 'test' + params: { + name: 'label1', + new_name: 'New Label', + color: '#FFFFFF', + description: 'test' + } expect(response).to have_gitlab_http_status(200) expect(json_response['name']).to eq('New Label') expect(json_response['color']).to eq('#FFFFFF') @@ -211,8 +231,10 @@ describe API::Labels do it 'returns 200 if name is changed' do put api("/projects/#{project.id}/labels", user), - name: 'label1', - new_name: 'New Label' + params: { + name: 'label1', + new_name: 'New Label' + } expect(response).to have_gitlab_http_status(200) expect(json_response['name']).to eq('New Label') expect(json_response['color']).to eq(label1.color) @@ -220,8 +242,10 @@ describe API::Labels do it 'returns 200 if colors is changed' do put api("/projects/#{project.id}/labels", user), - name: 'label1', - color: '#FFFFFF' + params: { + name: 'label1', + color: '#FFFFFF' + } expect(response).to have_gitlab_http_status(200) expect(json_response['name']).to eq(label1.name) expect(json_response['color']).to eq('#FFFFFF') @@ -229,8 +253,10 @@ describe API::Labels do it 'returns 200 if description is changed' do put api("/projects/#{project.id}/labels", user), - name: 'bug', - description: 'test' + params: { + name: 'bug', + description: 'test' + } expect(response).to have_gitlab_http_status(200) expect(json_response['name']).to eq(priority_label.name) @@ -240,8 +266,10 @@ describe API::Labels do it 'returns 200 if priority is changed' do put api("/projects/#{project.id}/labels", user), - name: 'bug', - priority: 10 + params: { + name: 'bug', + priority: 10 + } expect(response.status).to eq(200) expect(json_response['name']).to eq(priority_label.name) @@ -250,8 +278,10 @@ describe API::Labels do it 'returns 200 if a priority is added' do put api("/projects/#{project.id}/labels", user), - name: 'label1', - priority: 3 + params: { + name: 'label1', + priority: 3 + } expect(response.status).to eq(200) expect(json_response['name']).to eq(label1.name) @@ -260,8 +290,10 @@ describe API::Labels do it 'returns 200 if the priority is removed' do put api("/projects/#{project.id}/labels", user), - name: priority_label.name, - priority: nil + params: { + name: priority_label.name, + priority: nil + } expect(response.status).to eq(200) expect(json_response['name']).to eq(priority_label.name) @@ -270,19 +302,21 @@ describe API::Labels do it 'returns 404 if label does not exist' do put api("/projects/#{project.id}/labels", user), - name: 'label2', - new_name: 'label3' + params: { + name: 'label2', + new_name: 'label3' + } expect(response).to have_gitlab_http_status(404) end it 'returns 400 if no label name given' do - put api("/projects/#{project.id}/labels", user), new_name: 'label2' + put api("/projects/#{project.id}/labels", user), params: { new_name: 'label2' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('name is missing') end it 'returns 400 if no new parameters given' do - put api("/projects/#{project.id}/labels", user), name: 'label1' + put api("/projects/#{project.id}/labels", user), params: { name: 'label1' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('new_name, color, description, priority are missing, '\ 'at least one parameter must be provided') @@ -290,33 +324,41 @@ describe API::Labels do it 'returns 400 for invalid name' do put api("/projects/#{project.id}/labels", user), - name: 'label1', - new_name: ',', - color: '#FFFFFF' + params: { + name: 'label1', + new_name: ',', + color: '#FFFFFF' + } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['title']).to eq(['is invalid']) end it 'returns 400 when color code is too short' do put api("/projects/#{project.id}/labels", user), - name: 'label1', - color: '#FF' + params: { + name: 'label1', + color: '#FF' + } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['color']).to eq(['must be a valid color code']) end it 'returns 400 for too long color code' do put api("/projects/#{project.id}/labels", user), - name: 'label1', - color: '#FFAAFFFF' + params: { + name: 'label1', + color: '#FFAAFFFF' + } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['color']).to eq(['must be a valid color code']) end it 'returns 400 for invalid priority' do put api("/projects/#{project.id}/labels", user), - name: 'label1', - priority: 'foo' + params: { + name: 'label1', + priority: 'foo' + } expect(response).to have_gitlab_http_status(400) end diff --git a/spec/requests/api/lint_spec.rb b/spec/requests/api/lint_spec.rb index e3065840e6f..f52cdf1c459 100644 --- a/spec/requests/api/lint_spec.rb +++ b/spec/requests/api/lint_spec.rb @@ -8,7 +8,7 @@ describe API::Lint do end it 'passes validation' do - post api('/ci/lint'), { content: yaml_content } + post api('/ci/lint'), params: { content: yaml_content } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Hash @@ -19,7 +19,7 @@ describe API::Lint do context 'with an invalid .gitlab_ci.yml' do it 'responds with errors about invalid syntax' do - post api('/ci/lint'), { content: 'invalid content' } + post api('/ci/lint'), params: { content: 'invalid content' } expect(response).to have_gitlab_http_status(200) expect(json_response['status']).to eq('invalid') @@ -27,7 +27,7 @@ describe API::Lint do end it "responds with errors about invalid configuration" do - post api('/ci/lint'), { content: '{ image: "ruby:2.1", services: ["postgres"] }' } + post api('/ci/lint'), params: { content: '{ image: "ruby:2.1", services: ["postgres"] }' } expect(response).to have_gitlab_http_status(200) expect(json_response['status']).to eq('invalid') diff --git a/spec/requests/api/markdown_spec.rb b/spec/requests/api/markdown_spec.rb index e369c1435f0..e82ef002d32 100644 --- a/spec/requests/api/markdown_spec.rb +++ b/spec/requests/api/markdown_spec.rb @@ -7,7 +7,7 @@ describe API::Markdown do let(:user) {} # No-op. It gets overwritten in the contexts below. before do - post api("/markdown", user), params + post api("/markdown", user), params: params end shared_examples "rendered markdown text without GFM" do diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb index bb32d581176..79edbb301f2 100644 --- a/spec/requests/api/members_spec.rb +++ b/spec/requests/api/members_spec.rb @@ -78,7 +78,7 @@ describe API::Members do end it 'finds members with query string' do - get api(members_url, developer), query: maintainer.username + get api(members_url, developer), params: { query: maintainer.username } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -88,7 +88,7 @@ describe API::Members do end it 'finds all members with no query specified' do - get api(members_url, developer), query: '' + get api(members_url, developer), params: { query: '' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -178,7 +178,7 @@ describe API::Members do it_behaves_like 'a 404 response when source is private' do let(:route) do post api("/#{source_type.pluralize}/#{source.id}/members", stranger), - user_id: access_requester.id, access_level: Member::MAINTAINER + params: { user_id: access_requester.id, access_level: Member::MAINTAINER } end end @@ -188,7 +188,7 @@ describe API::Members do it 'returns 403' do user = public_send(type) post api("/#{source_type.pluralize}/#{source.id}/members", user), - user_id: access_requester.id, access_level: Member::MAINTAINER + params: { user_id: access_requester.id, access_level: Member::MAINTAINER } expect(response).to have_gitlab_http_status(403) end @@ -201,7 +201,7 @@ describe API::Members do it 'transforms the requester into a proper member' do expect do post api("/#{source_type.pluralize}/#{source.id}/members", maintainer), - user_id: access_requester.id, access_level: Member::MAINTAINER + params: { user_id: access_requester.id, access_level: Member::MAINTAINER } expect(response).to have_gitlab_http_status(201) end.to change { source.members.count }.by(1) @@ -214,7 +214,7 @@ describe API::Members do it 'creates a new member' do expect do post api("/#{source_type.pluralize}/#{source.id}/members", maintainer), - user_id: stranger.id, access_level: Member::DEVELOPER, expires_at: '2016-08-05' + params: { user_id: stranger.id, access_level: Member::DEVELOPER, expires_at: '2016-08-05' } expect(response).to have_gitlab_http_status(201) end.to change { source.members.count }.by(1) @@ -233,7 +233,7 @@ describe API::Members do parent.add_developer(stranger) post api("/#{source_type.pluralize}/#{source.id}/members", maintainer), - user_id: stranger.id, access_level: Member::REPORTER + params: { user_id: stranger.id, access_level: Member::REPORTER } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['access_level']).to eq(["should be higher than Developer inherited membership from group #{parent.name}"]) @@ -247,7 +247,7 @@ describe API::Members do parent.add_developer(stranger) post api("/#{source_type.pluralize}/#{source.id}/members", maintainer), - user_id: stranger.id, access_level: Member::MAINTAINER + params: { user_id: stranger.id, access_level: Member::MAINTAINER } expect(response).to have_gitlab_http_status(201) expect(json_response['id']).to eq(stranger.id) @@ -257,14 +257,14 @@ describe API::Members do it "returns 409 if member already exists" do post api("/#{source_type.pluralize}/#{source.id}/members", maintainer), - user_id: maintainer.id, access_level: Member::MAINTAINER + params: { user_id: maintainer.id, access_level: Member::MAINTAINER } expect(response).to have_gitlab_http_status(409) end it 'returns 404 when the user_id is not valid' do post api("/#{source_type.pluralize}/#{source.id}/members", maintainer), - user_id: 0, access_level: Member::MAINTAINER + params: { user_id: 0, access_level: Member::MAINTAINER } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 User Not Found') @@ -272,21 +272,21 @@ describe API::Members do it 'returns 400 when user_id is not given' do post api("/#{source_type.pluralize}/#{source.id}/members", maintainer), - access_level: Member::MAINTAINER + params: { access_level: Member::MAINTAINER } expect(response).to have_gitlab_http_status(400) end it 'returns 400 when access_level is not given' do post api("/#{source_type.pluralize}/#{source.id}/members", maintainer), - user_id: stranger.id + params: { user_id: stranger.id } expect(response).to have_gitlab_http_status(400) end it 'returns 400 when access_level is not valid' do post api("/#{source_type.pluralize}/#{source.id}/members", maintainer), - user_id: stranger.id, access_level: 1234 + params: { user_id: stranger.id, access_level: 1234 } expect(response).to have_gitlab_http_status(400) end @@ -298,7 +298,7 @@ describe API::Members do it_behaves_like 'a 404 response when source is private' do let(:route) do put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", stranger), - access_level: Member::MAINTAINER + params: { access_level: Member::MAINTAINER } end end @@ -308,7 +308,7 @@ describe API::Members do it 'returns 403' do user = public_send(type) put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user), - access_level: Member::MAINTAINER + params: { access_level: Member::MAINTAINER } expect(response).to have_gitlab_http_status(403) end @@ -319,7 +319,7 @@ describe API::Members do context 'when authenticated as a maintainer/owner' do it 'updates the member' do put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", maintainer), - access_level: Member::MAINTAINER, expires_at: '2016-08-05' + params: { access_level: Member::MAINTAINER, expires_at: '2016-08-05' } expect(response).to have_gitlab_http_status(200) expect(json_response['id']).to eq(developer.id) @@ -330,7 +330,7 @@ describe API::Members do it 'returns 409 if member does not exist' do put api("/#{source_type.pluralize}/#{source.id}/members/123", maintainer), - access_level: Member::MAINTAINER + params: { access_level: Member::MAINTAINER } expect(response).to have_gitlab_http_status(404) end @@ -343,7 +343,7 @@ describe API::Members do it 'returns 400 when access level is not valid' do put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", maintainer), - access_level: 1234 + params: { access_level: 1234 } expect(response).to have_gitlab_http_status(400) end @@ -457,7 +457,7 @@ describe API::Members do it 'returns 403' do expect do post api("/projects/#{project.id}/members", maintainer), - user_id: stranger.id, access_level: Member::OWNER + params: { user_id: stranger.id, access_level: Member::OWNER } expect(response).to have_gitlab_http_status(400) end.to change { project.members.count }.by(0) diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 27bcde77860..dd40f3d1561 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -45,7 +45,7 @@ describe API::MergeRequests do describe 'GET /merge_requests' do context 'when unauthenticated' do it 'returns an array of all merge requests' do - get api('/merge_requests', user), scope: 'all' + get api('/merge_requests', user), params: { scope: 'all' } expect_paginated_array_response end @@ -57,19 +57,19 @@ describe API::MergeRequests do end it "returns authentication error when scope is assigned-to-me" do - get api("/merge_requests"), scope: 'assigned-to-me' + get api("/merge_requests"), params: { scope: 'assigned-to-me' } expect(response).to have_gitlab_http_status(401) end it "returns authentication error when scope is assigned_to_me" do - get api("/merge_requests"), scope: 'assigned_to_me' + get api("/merge_requests"), params: { scope: 'assigned_to_me' } expect(response).to have_gitlab_http_status(401) end it "returns authentication error when scope is created-by-me" do - get api("/merge_requests"), scope: 'created-by-me' + get api("/merge_requests"), params: { scope: 'created-by-me' } expect(response).to have_gitlab_http_status(401) end @@ -81,7 +81,7 @@ describe API::MergeRequests do let(:user2) { create(:user) } it 'returns an array of all merge requests except unauthorized ones' do - get api('/merge_requests', user), scope: :all + get api('/merge_requests', user), params: { scope: :all } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -91,7 +91,7 @@ describe API::MergeRequests do end it "returns an array of no merge_requests when wip=yes" do - get api("/merge_requests", user), wip: 'yes' + get api("/merge_requests", user), params: { wip: 'yes' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -100,7 +100,7 @@ describe API::MergeRequests do end it "returns an array of no merge_requests when wip=no" do - get api("/merge_requests", user), wip: 'no' + get api("/merge_requests", user), params: { wip: 'no' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -113,7 +113,7 @@ describe API::MergeRequests do private_project = create(:project, :private) merge_request3 = create(:merge_request, :simple, source_project: private_project, target_project: private_project, source_branch: 'other-branch') - get api('/merge_requests', user), scope: :all + get api('/merge_requests', user), params: { scope: :all } expect_response_contain_exactly(merge_request2, merge_request_merged, merge_request_closed, merge_request, merge_request_locked) expect(json_response.map { |mr| mr['id'] }).not_to include(merge_request3.id) @@ -130,7 +130,7 @@ describe API::MergeRequests do it 'returns an array of merge requests authored by the given user' do merge_request3 = create(:merge_request, :simple, author: user2, assignee: user, source_project: project2, target_project: project2, source_branch: 'other-branch') - get api('/merge_requests', user), author_id: user2.id, scope: :all + get api('/merge_requests', user), params: { author_id: user2.id, scope: :all } expect_response_ordered_exactly(merge_request3) end @@ -138,7 +138,7 @@ describe API::MergeRequests do it 'returns an array of merge requests assigned to the given user' do merge_request3 = create(:merge_request, :simple, author: user, assignee: user2, source_project: project2, target_project: project2, source_branch: 'other-branch') - get api('/merge_requests', user), assignee_id: user2.id, scope: :all + get api('/merge_requests', user), params: { assignee_id: user2.id, scope: :all } expect_response_ordered_exactly(merge_request3) end @@ -146,7 +146,7 @@ describe API::MergeRequests do it 'returns an array of merge requests with no assignee' do merge_request3 = create(:merge_request, :simple, author: user, source_project: project2, target_project: project2, source_branch: 'other-branch') - get api('/merge_requests', user), assignee_id: 'None', scope: :all + get api('/merge_requests', user), params: { assignee_id: 'None', scope: :all } expect_response_ordered_exactly(merge_request3) end @@ -155,7 +155,7 @@ describe API::MergeRequests do # This MR with no assignee should not be returned create(:merge_request, :simple, author: user, source_project: project2, target_project: project2, source_branch: 'other-branch') - get api('/merge_requests', user), assignee_id: 'Any', scope: :all + get api('/merge_requests', user), params: { assignee_id: 'Any', scope: :all } expect_response_contain_exactly(merge_request, merge_request2, merge_request_closed, merge_request_merged, merge_request_locked) end @@ -163,7 +163,7 @@ describe API::MergeRequests do it 'returns an array of merge requests assigned to me' do merge_request3 = create(:merge_request, :simple, author: user, assignee: user2, source_project: project2, target_project: project2, source_branch: 'other-branch') - get api('/merge_requests', user2), scope: 'assigned_to_me' + get api('/merge_requests', user2), params: { scope: 'assigned_to_me' } expect_response_ordered_exactly(merge_request3) end @@ -171,7 +171,7 @@ describe API::MergeRequests do it 'returns an array of merge requests assigned to me (kebab-case)' do merge_request3 = create(:merge_request, :simple, author: user, assignee: user2, source_project: project2, target_project: project2, source_branch: 'other-branch') - get api('/merge_requests', user2), scope: 'assigned-to-me' + get api('/merge_requests', user2), params: { scope: 'assigned-to-me' } expect_response_ordered_exactly(merge_request3) end @@ -179,7 +179,7 @@ describe API::MergeRequests do it 'returns an array of merge requests created by me' do merge_request3 = create(:merge_request, :simple, author: user2, assignee: user, source_project: project2, target_project: project2, source_branch: 'other-branch') - get api('/merge_requests', user2), scope: 'created_by_me' + get api('/merge_requests', user2), params: { scope: 'created_by_me' } expect_response_ordered_exactly(merge_request3) end @@ -187,7 +187,7 @@ describe API::MergeRequests do it 'returns an array of merge requests created by me (kebab-case)' do merge_request3 = create(:merge_request, :simple, author: user2, assignee: user, source_project: project2, target_project: project2, source_branch: 'other-branch') - get api('/merge_requests', user2), scope: 'created-by-me' + get api('/merge_requests', user2), params: { scope: 'created-by-me' } expect_response_ordered_exactly(merge_request3) end @@ -196,14 +196,14 @@ describe API::MergeRequests do merge_request3 = create(:merge_request, :simple, author: user, assignee: user, source_project: project2, target_project: project2, source_branch: 'other-branch') award_emoji = create(:award_emoji, awardable: merge_request3, user: user2, name: 'star') - get api('/merge_requests', user2), my_reaction_emoji: award_emoji.name, scope: 'all' + get api('/merge_requests', user2), params: { my_reaction_emoji: award_emoji.name, scope: 'all' } expect_response_ordered_exactly(merge_request3) end context 'source_branch param' do it 'returns merge requests with the given source branch' do - get api('/merge_requests', user), source_branch: merge_request_closed.source_branch, state: 'all' + get api('/merge_requests', user), params: { source_branch: merge_request_closed.source_branch, state: 'all' } expect_response_contain_exactly(merge_request_closed, merge_request_merged, merge_request_locked) end @@ -211,7 +211,7 @@ describe API::MergeRequests do context 'target_branch param' do it 'returns merge requests with the given target branch' do - get api('/merge_requests', user), target_branch: merge_request_closed.target_branch, state: 'all' + get api('/merge_requests', user), params: { target_branch: merge_request_closed.target_branch, state: 'all' } expect_response_contain_exactly(merge_request_closed, merge_request_merged, merge_request_locked) end @@ -255,13 +255,13 @@ describe API::MergeRequests do end it 'returns merge requests matching given search string for title' do - get api("/merge_requests", user), search: merge_request.title + get api("/merge_requests", user), params: { search: merge_request.title } expect_response_ordered_exactly(merge_request) end it 'returns merge requests for project matching given search string for description' do - get api("/merge_requests", user), project_id: project.id, search: merge_request.description + get api("/merge_requests", user), params: { project_id: project.id, search: merge_request.description } expect_response_ordered_exactly(merge_request) end @@ -269,7 +269,7 @@ describe API::MergeRequests do context 'state param' do it 'returns merge requests with the given state' do - get api('/merge_requests', user), state: 'locked' + get api('/merge_requests', user), params: { state: 'locked' } expect_response_contain_exactly(merge_request_locked) end @@ -291,7 +291,7 @@ describe API::MergeRequests do end it "returns an array of no merge_requests when wip=yes" do - get api("/projects/#{project.id}/merge_requests", user), wip: 'yes' + get api("/projects/#{project.id}/merge_requests", user), params: { wip: 'yes' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -300,7 +300,7 @@ describe API::MergeRequests do end it 'returns merge_request by "iids" array' do - get api(endpoint_path, user), iids: [merge_request.iid, merge_request_closed.iid] + get api(endpoint_path, user), params: { iids: [merge_request.iid, merge_request_closed.iid] } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -364,7 +364,7 @@ describe API::MergeRequests do end it 'exposes description and title html when render_html is true' do - get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), render_html: true + get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { render_html: true } expect(response).to have_gitlab_http_status(200) @@ -372,7 +372,7 @@ describe API::MergeRequests do end it 'exposes rebase_in_progress when include_rebase_in_progress is true' do - get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), include_rebase_in_progress: true + get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { include_rebase_in_progress: true } expect(response).to have_gitlab_http_status(200) @@ -421,7 +421,7 @@ describe API::MergeRequests do it 'returns the commits behind the target branch when include_diverged_commits_count is present' do allow_any_instance_of(merge_request.class).to receive(:diverged_commits_count).and_return(1) - get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), include_diverged_commits_count: true + get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { include_diverged_commits_count: true } expect(response).to have_gitlab_http_status(200) expect(json_response['diverged_commits_count']).to eq(1) @@ -587,13 +587,15 @@ describe API::MergeRequests do context 'between branches projects' do it "returns merge_request" do post api("/projects/#{project.id}/merge_requests", user), - title: 'Test merge_request', - source_branch: 'feature_conflict', - target_branch: 'master', - author: user, - labels: 'label, label2', - milestone_id: milestone.id, - squash: true + params: { + title: 'Test merge_request', + source_branch: 'feature_conflict', + target_branch: 'master', + author: user, + labels: 'label, label2', + milestone_id: milestone.id, + squash: true + } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('Test merge_request') @@ -605,35 +607,37 @@ describe API::MergeRequests do it "returns 422 when source_branch equals target_branch" do post api("/projects/#{project.id}/merge_requests", user), - title: "Test merge_request", source_branch: "master", target_branch: "master", author: user + params: { title: "Test merge_request", source_branch: "master", target_branch: "master", author: user } expect(response).to have_gitlab_http_status(422) end it "returns 400 when source_branch is missing" do post api("/projects/#{project.id}/merge_requests", user), - title: "Test merge_request", target_branch: "master", author: user + params: { title: "Test merge_request", target_branch: "master", author: user } expect(response).to have_gitlab_http_status(400) end it "returns 400 when target_branch is missing" do post api("/projects/#{project.id}/merge_requests", user), - title: "Test merge_request", source_branch: "markdown", author: user + params: { title: "Test merge_request", source_branch: "markdown", author: user } expect(response).to have_gitlab_http_status(400) end it "returns 400 when title is missing" do post api("/projects/#{project.id}/merge_requests", user), - target_branch: 'master', source_branch: 'markdown' + params: { target_branch: 'master', source_branch: 'markdown' } expect(response).to have_gitlab_http_status(400) end it 'allows special label names' do post api("/projects/#{project.id}/merge_requests", user), - title: 'Test merge_request', - source_branch: 'markdown', - target_branch: 'master', - author: user, - labels: 'label, label?, label&foo, ?, &' + params: { + title: 'Test merge_request', + source_branch: 'markdown', + target_branch: 'master', + author: user, + labels: 'label, label?, label&foo, ?, &' + } expect(response).to have_gitlab_http_status(201) expect(json_response['labels']).to include 'label' expect(json_response['labels']).to include 'label?' @@ -645,20 +649,24 @@ describe API::MergeRequests do context 'with existing MR' do before do post api("/projects/#{project.id}/merge_requests", user), - title: 'Test merge_request', - source_branch: 'feature_conflict', - target_branch: 'master', - author: user + params: { + title: 'Test merge_request', + source_branch: 'feature_conflict', + target_branch: 'master', + author: user + } @mr = MergeRequest.all.last end it 'returns 409 when MR already exists for source/target' do expect do post api("/projects/#{project.id}/merge_requests", user), - title: 'New test merge_request', - source_branch: 'feature_conflict', - target_branch: 'master', - author: user + params: { + title: 'New test merge_request', + source_branch: 'feature_conflict', + target_branch: 'master', + author: user + } end.to change { MergeRequest.count }.by(0) expect(response).to have_gitlab_http_status(409) end @@ -673,13 +681,13 @@ describe API::MergeRequests do end it 'sets force_remove_source_branch to false' do - post api("/projects/#{project.id}/merge_requests", user), params.merge(remove_source_branch: false) + post api("/projects/#{project.id}/merge_requests", user), params: params.merge(remove_source_branch: false) expect(json_response['force_remove_source_branch']).to be_falsy end it 'sets force_remove_source_branch to true' do - post api("/projects/#{project.id}/merge_requests", user), params.merge(remove_source_branch: true) + post api("/projects/#{project.id}/merge_requests", user), params: params.merge(remove_source_branch: true) expect(json_response['force_remove_source_branch']).to be_truthy end @@ -698,8 +706,7 @@ describe API::MergeRequests do it "returns merge_request" do post api("/projects/#{forked_project.id}/merge_requests", user2), - title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master", - author: user2, target_project_id: project.id, description: 'Test description for Test merge_request' + params: { title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master", author: user2, target_project_id: project.id, description: 'Test description for Test merge_request' } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('Test merge_request') expect(json_response['description']).to eq('Test description for Test merge_request') @@ -710,7 +717,7 @@ describe API::MergeRequests do expect(forked_project.forked?).to be_truthy expect(forked_project.forked_from_project).to eq(project) post api("/projects/#{forked_project.id}/merge_requests", user2), - title: 'Test merge_request', source_branch: "master", target_branch: "master", author: user2, target_project_id: project.id + params: { title: 'Test merge_request', source_branch: "master", target_branch: "master", author: user2, target_project_id: project.id } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('Test merge_request') end @@ -719,37 +726,38 @@ describe API::MergeRequests do project.project_feature.update(merge_requests_access_level: 0) post api("/projects/#{forked_project.id}/merge_requests", user2), - title: 'Test', - target_branch: 'master', - source_branch: 'markdown', - author: user2, - target_project_id: project.id + params: { + title: 'Test', + target_branch: 'master', + source_branch: 'markdown', + author: user2, + target_project_id: project.id + } expect(response).to have_gitlab_http_status(403) end it "returns 400 when source_branch is missing" do post api("/projects/#{forked_project.id}/merge_requests", user2), - title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id + params: { title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id } expect(response).to have_gitlab_http_status(400) end it "returns 400 when target_branch is missing" do post api("/projects/#{forked_project.id}/merge_requests", user2), - title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id + params: { title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id } expect(response).to have_gitlab_http_status(400) end it "returns 400 when title is missing" do post api("/projects/#{forked_project.id}/merge_requests", user2), - target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: project.id + params: { target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: project.id } expect(response).to have_gitlab_http_status(400) end it 'allows setting `allow_collaboration`' do post api("/projects/#{forked_project.id}/merge_requests", user2), - title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master", - author: user2, target_project_id: project.id, allow_collaboration: true + params: { title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master", author: user2, target_project_id: project.id, allow_collaboration: true } expect(response).to have_gitlab_http_status(201) expect(json_response['allow_collaboration']).to be_truthy expect(json_response['allow_maintainer_to_push']).to be_truthy @@ -767,13 +775,13 @@ describe API::MergeRequests do it 'returns 422 if targeting a different fork' do unrelated_project.add_developer(user2) - post api("/projects/#{forked_project.id}/merge_requests", user2), params + post api("/projects/#{forked_project.id}/merge_requests", user2), params: params expect(response).to have_gitlab_http_status(422) end it 'returns 403 if targeting a different fork which user can not access' do - post api("/projects/#{forked_project.id}/merge_requests", user2), params + post api("/projects/#{forked_project.id}/merge_requests", user2), params: params expect(response).to have_gitlab_http_status(403) end @@ -781,7 +789,7 @@ describe API::MergeRequests do it "returns 201 when target_branch is specified and for the same project" do post api("/projects/#{forked_project.id}/merge_requests", user2), - title: 'Test merge_request', target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: forked_project.id + params: { title: 'Test merge_request', target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: forked_project.id } expect(response).to have_gitlab_http_status(201) end end @@ -877,21 +885,21 @@ describe API::MergeRequests do end it "returns 409 if the SHA parameter doesn't match" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), sha: merge_request.diff_head_sha.reverse + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: { sha: merge_request.diff_head_sha.reverse } expect(response).to have_gitlab_http_status(409) expect(json_response['message']).to start_with('SHA does not match HEAD of source branch') end it "succeeds if the SHA parameter matches" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), sha: merge_request.diff_head_sha + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: { sha: merge_request.diff_head_sha } expect(response).to have_gitlab_http_status(200) end it "updates the MR's squash attribute" do expect do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), squash: true + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: { squash: true } end.to change { merge_request.reload.squash } expect(response).to have_gitlab_http_status(200) @@ -901,7 +909,7 @@ describe API::MergeRequests do allow_any_instance_of(MergeRequest).to receive(:head_pipeline).and_return(pipeline) allow(pipeline).to receive(:active?).and_return(true) - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), merge_when_pipeline_succeeds: true + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: { merge_when_pipeline_succeeds: true } expect(response).to have_gitlab_http_status(200) expect(json_response['title']).to eq('Test') @@ -913,7 +921,7 @@ describe API::MergeRequests do allow(pipeline).to receive(:active?).and_return(true) project.update_attribute(:only_allow_merge_if_pipeline_succeeds, true) - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), merge_when_pipeline_succeeds: true + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: { merge_when_pipeline_succeeds: true } expect(response).to have_gitlab_http_status(200) expect(json_response['title']).to eq('Test') @@ -936,7 +944,7 @@ describe API::MergeRequests do describe "PUT /projects/:id/merge_requests/:merge_request_iid" do context "to close a MR" do it "returns merge_request" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), state_event: "close" + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { state_event: "close" } expect(response).to have_gitlab_http_status(200) expect(json_response['state']).to eq('closed') @@ -944,38 +952,38 @@ describe API::MergeRequests do end it "updates title and returns merge_request" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), title: "New title" + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { title: "New title" } expect(response).to have_gitlab_http_status(200) expect(json_response['title']).to eq('New title') end it "updates description and returns merge_request" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), description: "New description" + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { description: "New description" } expect(response).to have_gitlab_http_status(200) expect(json_response['description']).to eq('New description') end it "updates milestone_id and returns merge_request" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), milestone_id: milestone.id + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { milestone_id: milestone.id } expect(response).to have_gitlab_http_status(200) expect(json_response['milestone']['id']).to eq(milestone.id) end it "updates squash and returns merge_request" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), squash: true + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { squash: true } expect(response).to have_gitlab_http_status(200) expect(json_response['squash']).to be_truthy end it "returns merge_request with renamed target_branch" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), target_branch: "wiki" + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { target_branch: "wiki" } expect(response).to have_gitlab_http_status(200) expect(json_response['target_branch']).to eq('wiki') end it "returns merge_request that removes the source branch" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), remove_source_branch: true + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { remove_source_branch: true } expect(response).to have_gitlab_http_status(200) expect(json_response['force_remove_source_branch']).to be_truthy @@ -983,8 +991,10 @@ describe API::MergeRequests do it 'allows special label names' do put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), - title: 'new issue', - labels: 'label, label?, label&foo, ?, &' + params: { + title: 'new issue', + labels: 'label, label?, label&foo, ?, &' + } expect(response.status).to eq(200) expect(json_response['labels']).to include 'label' @@ -995,7 +1005,7 @@ describe API::MergeRequests do end it 'does not update state when title is empty' do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), state_event: 'close', title: nil + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { state_event: 'close', title: nil } merge_request.reload expect(response).to have_gitlab_http_status(400) @@ -1003,7 +1013,7 @@ describe API::MergeRequests do end it 'does not update state when target_branch is empty' do - put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), state_event: 'close', target_branch: nil + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { state_event: 'close', target_branch: nil } merge_request.reload expect(response).to have_gitlab_http_status(400) @@ -1011,13 +1021,13 @@ describe API::MergeRequests do end it "returns 404 for an invalid merge request IID" do - put api("/projects/#{project.id}/merge_requests/12345", user), state_event: "close" + put api("/projects/#{project.id}/merge_requests/12345", user), params: { state_event: "close" } expect(response).to have_gitlab_http_status(404) end it "returns 404 if the merge request id is used instead of iid" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), state_event: "close" + put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), params: { state_event: "close" } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb index 3fb45449c74..9bf753fe049 100644 --- a/spec/requests/api/notes_spec.rb +++ b/spec/requests/api/notes_spec.rb @@ -28,7 +28,7 @@ describe API::Notes do # before do post api("/projects/#{private_issue.project.id}/issues/#{private_issue.iid}/notes", user), - body: 'Hi!' + params: { body: 'Hi!' } end it 'responds with resource not found error' do @@ -154,7 +154,7 @@ describe API::Notes do end context 'when a user is a team member' do - subject { post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes", user), body: 'Hi!' } + subject { post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes", user), params: { body: 'Hi!' } } it 'returns 200 status' do subject @@ -168,7 +168,7 @@ describe API::Notes do end context 'when a user is not a team member' do - subject { post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes", private_user), body: 'Hi!' } + subject { post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes", private_user), params: { body: 'Hi!' } } it 'returns 403 status' do subject diff --git a/spec/requests/api/notification_settings_spec.rb b/spec/requests/api/notification_settings_spec.rb index 3273cd26690..4ed667ad0dc 100644 --- a/spec/requests/api/notification_settings_spec.rb +++ b/spec/requests/api/notification_settings_spec.rb @@ -20,7 +20,7 @@ describe API::NotificationSettings do let(:email) { create(:email, user: user) } it "updates global notification settings for the current user" do - put api("/notification_settings", user), { level: 'watch', notification_email: email.email } + put api("/notification_settings", user), params: { level: 'watch', notification_email: email.email } expect(response).to have_gitlab_http_status(200) expect(json_response['notification_email']).to eq(email.email) @@ -31,7 +31,7 @@ describe API::NotificationSettings do describe "PUT /notification_settings" do it "fails on non-user email address" do - put api("/notification_settings", user), { notification_email: 'invalid@example.com' } + put api("/notification_settings", user), params: { notification_email: 'invalid@example.com' } expect(response).to have_gitlab_http_status(400) end @@ -49,7 +49,7 @@ describe API::NotificationSettings do describe "PUT /groups/:id/notification_settings" do it "updates group level notification settings for the current user" do - put api("/groups/#{group.id}/notification_settings", user), { level: 'watch' } + put api("/groups/#{group.id}/notification_settings", user), params: { level: 'watch' } expect(response).to have_gitlab_http_status(200) expect(json_response['level']).to eq(user.reload.notification_settings_for(group).level) @@ -68,7 +68,7 @@ describe API::NotificationSettings do describe "PUT /projects/:id/notification_settings" do it "updates project level notification settings for the current user" do - put api("/projects/#{project.id}/notification_settings", user), { level: 'custom', new_note: true } + put api("/projects/#{project.id}/notification_settings", user), params: { level: 'custom', new_note: true } expect(response).to have_gitlab_http_status(200) expect(json_response['level']).to eq(user.reload.notification_settings_for(project).level) @@ -79,7 +79,7 @@ describe API::NotificationSettings do describe "PUT /projects/:id/notification_settings" do it "fails on invalid level" do - put api("/projects/#{project.id}/notification_settings", user), { level: 'invalid' } + put api("/projects/#{project.id}/notification_settings", user), params: { level: 'invalid' } expect(response).to have_gitlab_http_status(400) end diff --git a/spec/requests/api/oauth_tokens_spec.rb b/spec/requests/api/oauth_tokens_spec.rb index bdda80cc229..3811ec751de 100644 --- a/spec/requests/api/oauth_tokens_spec.rb +++ b/spec/requests/api/oauth_tokens_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'OAuth tokens' do context 'Resource Owner Password Credentials' do def request_oauth_token(user) - post '/oauth/token', username: user.username, password: user.password, grant_type: 'password' + post '/oauth/token', params: { username: user.username, password: user.password, grant_type: 'password' } end context 'when user has 2FA enabled' do diff --git a/spec/requests/api/pages_domains_spec.rb b/spec/requests/api/pages_domains_spec.rb index 35b6ed8d5c0..3eb68a6abb6 100644 --- a/spec/requests/api/pages_domains_spec.rb +++ b/spec/requests/api/pages_domains_spec.rb @@ -236,7 +236,7 @@ describe API::PagesDomains do shared_examples_for 'post pages domains' do it 'creates a new pages domain' do - post api(route, user), params + post api(route, user), params: params pages_domain = PagesDomain.find_by(domain: json_response['domain']) expect(response).to have_gitlab_http_status(201) @@ -247,7 +247,7 @@ describe API::PagesDomains do end it 'creates a new secure pages domain' do - post api(route, user), params_secure + post api(route, user), params: params_secure pages_domain = PagesDomain.find_by(domain: json_response['domain']) expect(response).to have_gitlab_http_status(201) @@ -258,13 +258,13 @@ describe API::PagesDomains do end it 'fails to create pages domain without key' do - post api(route, user), pages_domain_secure_params.slice(:domain, :certificate) + post api(route, user), params: pages_domain_secure_params.slice(:domain, :certificate) expect(response).to have_gitlab_http_status(400) end it 'fails to create pages domain with key missmatch' do - post api(route, user), pages_domain_secure_key_missmatch_params.slice(:domain, :certificate, :key) + post api(route, user), params: pages_domain_secure_key_missmatch_params.slice(:domain, :certificate, :key) expect(response).to have_gitlab_http_status(400) end @@ -284,7 +284,7 @@ describe API::PagesDomains do end it_behaves_like '403 response' do - let(:request) { post api(route, user), params } + let(:request) { post api(route, user), params: params } end end @@ -294,7 +294,7 @@ describe API::PagesDomains do end it_behaves_like '403 response' do - let(:request) { post api(route, user), params } + let(:request) { post api(route, user), params: params } end end @@ -304,13 +304,13 @@ describe API::PagesDomains do end it_behaves_like '403 response' do - let(:request) { post api(route, user), params } + let(:request) { post api(route, user), params: params } end end context 'when user is not a member' do it_behaves_like '404 response' do - let(:request) { post api(route, user), params } + let(:request) { post api(route, user), params: params } end end end @@ -331,7 +331,7 @@ describe API::PagesDomains do end it 'updates pages domain adding certificate' do - put api(route_domain, user), params_secure + put api(route_domain, user), params: params_secure pages_domain.reload expect(response).to have_gitlab_http_status(200) @@ -341,7 +341,7 @@ describe API::PagesDomains do end it 'updates pages domain with expired certificate' do - put api(route_expired_domain, user), params_secure + put api(route_expired_domain, user), params: params_secure pages_domain_expired.reload expect(response).to have_gitlab_http_status(200) @@ -351,7 +351,7 @@ describe API::PagesDomains do end it 'updates pages domain with expired certificate not updating key' do - put api(route_secure_domain, user), params_secure_nokey + put api(route_secure_domain, user), params: params_secure_nokey pages_domain_secure.reload expect(response).to have_gitlab_http_status(200) @@ -360,19 +360,19 @@ describe API::PagesDomains do end it 'fails to update pages domain adding certificate without key' do - put api(route_domain, user), params_secure_nokey + put api(route_domain, user), params: params_secure_nokey expect(response).to have_gitlab_http_status(400) end it 'fails to update pages domain adding certificate with missing chain' do - put api(route_domain, user), pages_domain_secure_missing_chain_params.slice(:certificate) + put api(route_domain, user), params: pages_domain_secure_missing_chain_params.slice(:certificate) expect(response).to have_gitlab_http_status(400) end it 'fails to update pages domain with key missmatch' do - put api(route_secure_domain, user), pages_domain_secure_key_missmatch_params.slice(:certificate, :key) + put api(route_secure_domain, user), params: pages_domain_secure_key_missmatch_params.slice(:certificate, :key) expect(response).to have_gitlab_http_status(400) end diff --git a/spec/requests/api/pipeline_schedules_spec.rb b/spec/requests/api/pipeline_schedules_spec.rb index 997d413eb4f..870ef34437f 100644 --- a/spec/requests/api/pipeline_schedules_spec.rb +++ b/spec/requests/api/pipeline_schedules_spec.rb @@ -58,7 +58,7 @@ describe API::PipelineSchedules do end it 'returns matched pipeline schedules' do - get api("/projects/#{project.id}/pipeline_schedules", developer), scope: target + get api("/projects/#{project.id}/pipeline_schedules", developer), params: { scope: target } expect(json_response.map { |r| r['active'] }).to all(eq(active?(target))) end @@ -146,7 +146,7 @@ describe API::PipelineSchedules do it 'creates pipeline_schedule' do expect do post api("/projects/#{project.id}/pipeline_schedules", developer), - params + params: params end.to change { project.pipeline_schedules.count }.by(1) expect(response).to have_gitlab_http_status(:created) @@ -170,7 +170,7 @@ describe API::PipelineSchedules do context 'when cron has validation error' do it 'does not create pipeline_schedule' do post api("/projects/#{project.id}/pipeline_schedules", developer), - params.merge('cron' => 'invalid-cron') + params: params.merge('cron' => 'invalid-cron') expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to have_key('cron') @@ -180,7 +180,7 @@ describe API::PipelineSchedules do context 'authenticated user with invalid permissions' do it 'does not create pipeline_schedule' do - post api("/projects/#{project.id}/pipeline_schedules", user), params + post api("/projects/#{project.id}/pipeline_schedules", user), params: params expect(response).to have_gitlab_http_status(:not_found) end @@ -188,7 +188,7 @@ describe API::PipelineSchedules do context 'unauthenticated user' do it 'does not create pipeline_schedule' do - post api("/projects/#{project.id}/pipeline_schedules"), params + post api("/projects/#{project.id}/pipeline_schedules"), params: params expect(response).to have_gitlab_http_status(:unauthorized) end @@ -203,7 +203,7 @@ describe API::PipelineSchedules do context 'authenticated user with valid permissions' do it 'updates cron' do put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", developer), - cron: '1 2 3 4 *' + params: { cron: '1 2 3 4 *' } expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('pipeline_schedule') @@ -213,7 +213,7 @@ describe API::PipelineSchedules do context 'when cron has validation error' do it 'does not update pipeline_schedule' do put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", developer), - cron: 'invalid-cron' + params: { cron: 'invalid-cron' } expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to have_key('cron') @@ -331,7 +331,7 @@ describe API::PipelineSchedules do it 'creates pipeline_schedule_variable' do expect do post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", developer), - params + params: params end.to change { pipeline_schedule.variables.count }.by(1) expect(response).to have_gitlab_http_status(:created) @@ -352,7 +352,7 @@ describe API::PipelineSchedules do context 'when key has validation error' do it 'does not create pipeline_schedule_variable' do post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", developer), - params.merge('key' => '!?!?') + params: params.merge('key' => '!?!?') expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to have_key('key') @@ -362,7 +362,7 @@ describe API::PipelineSchedules do context 'authenticated user with invalid permissions' do it 'does not create pipeline_schedule_variable' do - post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", user), params + post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", user), params: params expect(response).to have_gitlab_http_status(:not_found) end @@ -370,7 +370,7 @@ describe API::PipelineSchedules do context 'unauthenticated user' do it 'does not create pipeline_schedule_variable' do - post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables"), params + post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables"), params: params expect(response).to have_gitlab_http_status(:unauthorized) end @@ -389,7 +389,7 @@ describe API::PipelineSchedules do context 'authenticated user with valid permissions' do it 'updates pipeline_schedule_variable' do put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", developer), - value: 'updated_value' + params: { value: 'updated_value' } expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('pipeline_schedule_variable') diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb index 2e4fa0f9e16..eb002de62a2 100644 --- a/spec/requests/api/pipelines_spec.rb +++ b/spec/requests/api/pipelines_spec.rb @@ -36,7 +36,7 @@ describe API::Pipelines do end it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), scope: target + get api("/projects/#{project.id}/pipelines", user), params: { scope: target } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -54,7 +54,7 @@ describe API::Pipelines do end it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), scope: 'finished' + get api("/projects/#{project.id}/pipelines", user), params: { scope: 'finished' } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -69,7 +69,7 @@ describe API::Pipelines do context 'when scope is branches' do it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), scope: 'branches' + get api("/projects/#{project.id}/pipelines", user), params: { scope: 'branches' } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -80,7 +80,7 @@ describe API::Pipelines do context 'when scope is tags' do it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), scope: 'tags' + get api("/projects/#{project.id}/pipelines", user), params: { scope: 'tags' } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -92,7 +92,7 @@ describe API::Pipelines do context 'when scope is invalid' do it 'returns bad_request' do - get api("/projects/#{project.id}/pipelines", user), scope: 'invalid-scope' + get api("/projects/#{project.id}/pipelines", user), params: { scope: 'invalid-scope' } expect(response).to have_gitlab_http_status(:bad_request) end @@ -107,7 +107,7 @@ describe API::Pipelines do end it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), status: target + get api("/projects/#{project.id}/pipelines", user), params: { status: target } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -119,7 +119,7 @@ describe API::Pipelines do context 'when status is invalid' do it 'returns bad_request' do - get api("/projects/#{project.id}/pipelines", user), status: 'invalid-status' + get api("/projects/#{project.id}/pipelines", user), params: { status: 'invalid-status' } expect(response).to have_gitlab_http_status(:bad_request) end @@ -132,7 +132,7 @@ describe API::Pipelines do context 'when ref exists' do it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), ref: 'master' + get api("/projects/#{project.id}/pipelines", user), params: { ref: 'master' } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -143,7 +143,7 @@ describe API::Pipelines do context 'when ref does not exist' do it 'returns empty' do - get api("/projects/#{project.id}/pipelines", user), ref: 'invalid-ref' + get api("/projects/#{project.id}/pipelines", user), params: { ref: 'invalid-ref' } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -157,7 +157,7 @@ describe API::Pipelines do context 'when name exists' do it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), name: user.name + get api("/projects/#{project.id}/pipelines", user), params: { name: user.name } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -167,7 +167,7 @@ describe API::Pipelines do context 'when name does not exist' do it 'returns empty' do - get api("/projects/#{project.id}/pipelines", user), name: 'invalid-name' + get api("/projects/#{project.id}/pipelines", user), params: { name: 'invalid-name' } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -181,7 +181,7 @@ describe API::Pipelines do context 'when username exists' do it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), username: user.username + get api("/projects/#{project.id}/pipelines", user), params: { username: user.username } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -191,7 +191,7 @@ describe API::Pipelines do context 'when username does not exist' do it 'returns empty' do - get api("/projects/#{project.id}/pipelines", user), username: 'invalid-username' + get api("/projects/#{project.id}/pipelines", user), params: { username: 'invalid-username' } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -206,7 +206,7 @@ describe API::Pipelines do context 'when yaml_errors is true' do it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), yaml_errors: true + get api("/projects/#{project.id}/pipelines", user), params: { yaml_errors: true } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -216,7 +216,7 @@ describe API::Pipelines do context 'when yaml_errors is false' do it 'returns matched pipelines' do - get api("/projects/#{project.id}/pipelines", user), yaml_errors: false + get api("/projects/#{project.id}/pipelines", user), params: { yaml_errors: false } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -226,7 +226,7 @@ describe API::Pipelines do context 'when yaml_errors is invalid' do it 'returns bad_request' do - get api("/projects/#{project.id}/pipelines", user), yaml_errors: 'invalid-yaml_errors' + get api("/projects/#{project.id}/pipelines", user), params: { yaml_errors: 'invalid-yaml_errors' } expect(response).to have_gitlab_http_status(:bad_request) end @@ -243,7 +243,7 @@ describe API::Pipelines do context 'when sort parameter is valid' do it 'sorts as user_id: :desc' do - get api("/projects/#{project.id}/pipelines", user), order_by: 'user_id', sort: 'desc' + get api("/projects/#{project.id}/pipelines", user), params: { order_by: 'user_id', sort: 'desc' } expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -256,7 +256,7 @@ describe API::Pipelines do context 'when sort parameter is invalid' do it 'returns bad_request' do - get api("/projects/#{project.id}/pipelines", user), order_by: 'user_id', sort: 'invalid_sort' + get api("/projects/#{project.id}/pipelines", user), params: { order_by: 'user_id', sort: 'invalid_sort' } expect(response).to have_gitlab_http_status(:bad_request) end @@ -265,7 +265,7 @@ describe API::Pipelines do context 'when order_by is invalid' do it 'returns bad_request' do - get api("/projects/#{project.id}/pipelines", user), order_by: 'lock_version', sort: 'asc' + get api("/projects/#{project.id}/pipelines", user), params: { order_by: 'lock_version', sort: 'asc' } expect(response).to have_gitlab_http_status(:bad_request) end @@ -303,7 +303,7 @@ describe API::Pipelines do it 'creates and returns a new pipeline' do expect do - post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch + post api("/projects/#{project.id}/pipeline", user), params: { ref: project.default_branch } end.to change { project.ci_pipelines.count }.by(1) expect(response).to have_gitlab_http_status(201) @@ -316,7 +316,7 @@ describe API::Pipelines do it 'creates and returns a new pipeline using the given variables' do expect do - post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch, variables: variables + post api("/projects/#{project.id}/pipeline", user), params: { ref: project.default_branch, variables: variables } end.to change { project.ci_pipelines.count }.by(1) expect_variables(project.ci_pipelines.last.variables, variables) @@ -337,7 +337,7 @@ describe API::Pipelines do it 'creates and returns a new pipeline using the given variables' do expect do - post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch, variables: variables + post api("/projects/#{project.id}/pipeline", user), params: { ref: project.default_branch, variables: variables } end.to change { project.ci_pipelines.count }.by(1) expect_variables(project.ci_pipelines.last.variables, variables) @@ -352,7 +352,7 @@ describe API::Pipelines do it "doesn't create a job" do expect do - post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch + post api("/projects/#{project.id}/pipeline", user), params: { ref: project.default_branch } end.not_to change { project.ci_pipelines.count } expect(response).to have_gitlab_http_status(400) @@ -361,7 +361,7 @@ describe API::Pipelines do end it 'fails when using an invalid ref' do - post api("/projects/#{project.id}/pipeline", user), ref: 'invalid_ref' + post api("/projects/#{project.id}/pipeline", user), params: { ref: 'invalid_ref' } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['base'].first).to eq 'Reference not found' @@ -376,7 +376,7 @@ describe API::Pipelines do end it 'fails to create pipeline' do - post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch + post api("/projects/#{project.id}/pipeline", user), params: { ref: project.default_branch } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['base'].first).to eq 'Missing .gitlab-ci.yml file' @@ -388,7 +388,7 @@ describe API::Pipelines do context 'unauthorized user' do it 'does not create pipeline' do - post api("/projects/#{project.id}/pipeline", non_member), ref: project.default_branch + post api("/projects/#{project.id}/pipeline", non_member), params: { ref: project.default_branch } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq '404 Project Not Found' diff --git a/spec/requests/api/project_export_spec.rb b/spec/requests/api/project_export_spec.rb index 0586025956f..1d2f81a397d 100644 --- a/spec/requests/api/project_export_spec.rb +++ b/spec/requests/api/project_export_spec.rb @@ -294,14 +294,14 @@ describe API::ProjectExport do context 'with upload strategy' do context 'when params invalid' do it_behaves_like '400 response' do - let(:request) { post(api(path, user), 'upload[url]' => 'whatever') } + let(:request) { post(api(path, user), params: { 'upload[url]' => 'whatever' }) } end end it 'starts' do allow_any_instance_of(Gitlab::ImportExport::AfterExportStrategies::WebUploadStrategy).to receive(:send_file) - post(api(path, user), 'upload[url]' => 'http://gitlab.com') + post(api(path, user), params: { 'upload[url]' => 'http://gitlab.com' }) expect(response).to have_gitlab_http_status(202) end @@ -374,7 +374,7 @@ describe API::ProjectExport do params = { description: "Foo" } expect_any_instance_of(Projects::ImportExport::ExportService).to receive(:execute) - post api(path, project.owner), params + post api(path, project.owner), params: params expect(response).to have_gitlab_http_status(202) end diff --git a/spec/requests/api/project_hooks_spec.rb b/spec/requests/api/project_hooks_spec.rb index 87997a48dc9..b88a8b95201 100644 --- a/spec/requests/api/project_hooks_spec.rb +++ b/spec/requests/api/project_hooks_spec.rb @@ -91,8 +91,7 @@ describe API::ProjectHooks, 'ProjectHooks' do it "adds hook to project" do expect do post api("/projects/#{project.id}/hooks", user), - url: "http://example.com", issues_events: true, confidential_issues_events: true, wiki_page_events: true, - job_events: true, push_events_branch_filter: 'some-feature-branch' + params: { url: "http://example.com", issues_events: true, confidential_issues_events: true, wiki_page_events: true, job_events: true, push_events_branch_filter: 'some-feature-branch' } end.to change {project.hooks.count}.by(1) expect(response).to have_gitlab_http_status(201) @@ -116,7 +115,7 @@ describe API::ProjectHooks, 'ProjectHooks' do token = "secret token" expect do - post api("/projects/#{project.id}/hooks", user), url: "http://example.com", token: token + post api("/projects/#{project.id}/hooks", user), params: { url: "http://example.com", token: token } end.to change {project.hooks.count}.by(1) expect(response).to have_gitlab_http_status(201) @@ -135,12 +134,12 @@ describe API::ProjectHooks, 'ProjectHooks' do end it "returns a 422 error if url not valid" do - post api("/projects/#{project.id}/hooks", user), url: "ftp://example.com" + post api("/projects/#{project.id}/hooks", user), params: { url: "ftp://example.com" } expect(response).to have_gitlab_http_status(422) end it "returns a 422 error if branch filter is not valid" do - post api("/projects/#{project.id}/hooks", user), url: "http://example.com", push_events_branch_filter: '~badbranchname/' + post api("/projects/#{project.id}/hooks", user), params: { url: "http://example.com", push_events_branch_filter: '~badbranchname/' } expect(response).to have_gitlab_http_status(422) end end @@ -148,7 +147,7 @@ describe API::ProjectHooks, 'ProjectHooks' do describe "PUT /projects/:id/hooks/:hook_id" do it "updates an existing project hook" do put api("/projects/#{project.id}/hooks/#{hook.id}", user), - url: 'http://example.org', push_events: false, job_events: true + params: { url: 'http://example.org', push_events: false, job_events: true } expect(response).to have_gitlab_http_status(200) expect(json_response['url']).to eq('http://example.org') @@ -168,7 +167,7 @@ describe API::ProjectHooks, 'ProjectHooks' do it "adds the token without including it in the response" do token = "secret token" - put api("/projects/#{project.id}/hooks/#{hook.id}", user), url: "http://example.org", token: token + put api("/projects/#{project.id}/hooks/#{hook.id}", user), params: { url: "http://example.org", token: token } expect(response).to have_gitlab_http_status(200) expect(json_response["url"]).to eq("http://example.org") @@ -179,7 +178,7 @@ describe API::ProjectHooks, 'ProjectHooks' do end it "returns 404 error if hook id not found" do - put api("/projects/#{project.id}/hooks/1234", user), url: 'http://example.org' + put api("/projects/#{project.id}/hooks/1234", user), params: { url: 'http://example.org' } expect(response).to have_gitlab_http_status(404) end @@ -189,7 +188,7 @@ describe API::ProjectHooks, 'ProjectHooks' do end it "returns a 422 error if url is not valid" do - put api("/projects/#{project.id}/hooks/#{hook.id}", user), url: 'ftp://example.com' + put api("/projects/#{project.id}/hooks/#{hook.id}", user), params: { url: 'ftp://example.com' } expect(response).to have_gitlab_http_status(422) end end diff --git a/spec/requests/api/project_import_spec.rb b/spec/requests/api/project_import_spec.rb index 204702b8a5a..594b42bb6c0 100644 --- a/spec/requests/api/project_import_spec.rb +++ b/spec/requests/api/project_import_spec.rb @@ -20,7 +20,7 @@ describe API::ProjectImport do it 'schedules an import using a namespace' do stub_import(namespace) - post api('/projects/import', user), path: 'test-import', file: fixture_file_upload(file), namespace: namespace.id + post api('/projects/import', user), params: { path: 'test-import', file: fixture_file_upload(file), namespace: namespace.id } expect(response).to have_gitlab_http_status(201) end @@ -28,7 +28,7 @@ describe API::ProjectImport do it 'schedules an import using the namespace path' do stub_import(namespace) - post api('/projects/import', user), path: 'test-import', file: fixture_file_upload(file), namespace: namespace.full_path + post api('/projects/import', user), params: { path: 'test-import', file: fixture_file_upload(file), namespace: namespace.full_path } expect(response).to have_gitlab_http_status(201) end @@ -36,7 +36,7 @@ describe API::ProjectImport do it 'schedules an import at the user namespace level' do stub_import(user.namespace) - post api('/projects/import', user), path: 'test-import2', file: fixture_file_upload(file) + post api('/projects/import', user), params: { path: 'test-import2', file: fixture_file_upload(file) } expect(response).to have_gitlab_http_status(201) end @@ -45,7 +45,7 @@ describe API::ProjectImport do expect_any_instance_of(ProjectImportState).not_to receive(:schedule) expect(::Projects::CreateService).not_to receive(:new) - post api('/projects/import', user), namespace: 'nonexistent', path: 'test-import2', file: fixture_file_upload(file) + post api('/projects/import', user), params: { namespace: 'nonexistent', path: 'test-import2', file: fixture_file_upload(file) } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Namespace Not Found') @@ -55,9 +55,11 @@ describe API::ProjectImport do expect_any_instance_of(ProjectImportState).not_to receive(:schedule) post(api('/projects/import', create(:user)), - path: 'test-import3', - file: fixture_file_upload(file), - namespace: namespace.full_path) + params: { + path: 'test-import3', + file: fixture_file_upload(file), + namespace: namespace.full_path + }) expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Namespace Not Found') @@ -66,7 +68,7 @@ describe API::ProjectImport do it 'does not schedule an import if the user uploads no valid file' do expect_any_instance_of(ProjectImportState).not_to receive(:schedule) - post api('/projects/import', user), path: 'test-import3', file: './random/test' + post api('/projects/import', user), params: { path: 'test-import3', file: './random/test' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('file is invalid') @@ -77,10 +79,12 @@ describe API::ProjectImport do override_params = { 'description' => 'Hello world' } post api('/projects/import', user), - path: 'test-import', - file: fixture_file_upload(file), - namespace: namespace.id, - override_params: override_params + params: { + path: 'test-import', + file: fixture_file_upload(file), + namespace: namespace.id, + override_params: override_params + } import_project = Project.find(json_response['id']) expect(import_project.import_data.data['override_params']).to eq(override_params) @@ -91,10 +95,12 @@ describe API::ProjectImport do override_params = { 'not_allowed' => 'Hello world' } post api('/projects/import', user), - path: 'test-import', - file: fixture_file_upload(file), - namespace: namespace.id, - override_params: override_params + params: { + path: 'test-import', + file: fixture_file_upload(file), + namespace: namespace.id, + override_params: override_params + } import_project = Project.find(json_response['id']) expect(import_project.import_data.data['override_params']).to be_empty @@ -105,10 +111,12 @@ describe API::ProjectImport do perform_enqueued_jobs do post api('/projects/import', user), - path: 'test-import', - file: fixture_file_upload(file), - namespace: namespace.id, - override_params: override_params + params: { + path: 'test-import', + file: fixture_file_upload(file), + namespace: namespace.id, + override_params: override_params + } end import_project = Project.find(json_response['id']) @@ -121,7 +129,7 @@ describe API::ProjectImport do it 'does not schedule an import' do expect_any_instance_of(ProjectImportState).not_to receive(:schedule) - post api('/projects/import', user), path: existing_project.path, file: fixture_file_upload(file) + post api('/projects/import', user), params: { path: existing_project.path, file: fixture_file_upload(file) } expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('Name has already been taken') @@ -131,7 +139,7 @@ describe API::ProjectImport do it 'schedules an import' do stub_import(user.namespace) - post api('/projects/import', user), path: existing_project.path, file: fixture_file_upload(file), overwrite: true + post api('/projects/import', user), params: { path: existing_project.path, file: fixture_file_upload(file), overwrite: true } expect(response).to have_gitlab_http_status(201) end diff --git a/spec/requests/api/project_milestones_spec.rb b/spec/requests/api/project_milestones_spec.rb index 62613aa5938..0fa13dd71e2 100644 --- a/spec/requests/api/project_milestones_spec.rb +++ b/spec/requests/api/project_milestones_spec.rb @@ -46,7 +46,7 @@ describe API::ProjectMilestones do expect(Event).to receive(:create!) put api("/projects/#{project.id}/milestones/#{milestone.id}", user), - state_event: 'close' + params: { state_event: 'close' } end end end diff --git a/spec/requests/api/project_snapshots_spec.rb b/spec/requests/api/project_snapshots_spec.rb index 07a920f8d28..44b5ee1f130 100644 --- a/spec/requests/api/project_snapshots_spec.rb +++ b/spec/requests/api/project_snapshots_spec.rb @@ -35,14 +35,14 @@ describe API::ProjectSnapshots do end it 'requests project repository raw archive as administrator' do - get api("/projects/#{project.id}/snapshot", admin), wiki: '0' + get api("/projects/#{project.id}/snapshot", admin), params: { wiki: '0' } expect(response).to have_gitlab_http_status(200) expect_snapshot_response_for(project.repository) end it 'requests wiki repository raw archive as administrator' do - get api("/projects/#{project.id}/snapshot", admin), wiki: '1' + get api("/projects/#{project.id}/snapshot", admin), params: { wiki: '1' } expect(response).to have_gitlab_http_status(200) expect_snapshot_response_for(project.wiki.repository) diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb index 5dec0bc778c..29f69b6ce20 100644 --- a/spec/requests/api/project_snippets_spec.rb +++ b/spec/requests/api/project_snippets_spec.rb @@ -97,7 +97,7 @@ describe API::ProjectSnippets do end it 'creates a new snippet' do - post api("/projects/#{project.id}/snippets/", admin), params + post api("/projects/#{project.id}/snippets/", admin), params: params expect(response).to have_gitlab_http_status(201) snippet = ProjectSnippet.find(json_response['id']) @@ -111,7 +111,7 @@ describe API::ProjectSnippets do it 'returns 400 for missing parameters' do params.delete(:title) - post api("/projects/#{project.id}/snippets/", admin), params + post api("/projects/#{project.id}/snippets/", admin), params: params expect(response).to have_gitlab_http_status(400) end @@ -119,7 +119,7 @@ describe API::ProjectSnippets do it 'returns 400 for empty code field' do params[:code] = '' - post api("/projects/#{project.id}/snippets/", admin), params + post api("/projects/#{project.id}/snippets/", admin), params: params expect(response).to have_gitlab_http_status(400) end @@ -128,7 +128,7 @@ describe API::ProjectSnippets do def create_snippet(project, snippet_params = {}) project.add_developer(user) - post api("/projects/#{project.id}/snippets", user), params.merge(snippet_params) + post api("/projects/#{project.id}/snippets", user), params: params.merge(snippet_params) end before do @@ -167,7 +167,7 @@ describe API::ProjectSnippets do new_content = 'New content' new_description = 'New description' - put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content, description: new_description + put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), params: { code: new_content, description: new_description } expect(response).to have_gitlab_http_status(200) snippet.reload @@ -176,7 +176,7 @@ describe API::ProjectSnippets do end it 'returns 404 for invalid snippet id' do - put api("/projects/#{snippet.project.id}/snippets/1234", admin), title: 'foo' + put api("/projects/#{snippet.project.id}/snippets/1234", admin), params: { title: 'foo' } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Snippet Not Found') @@ -191,14 +191,14 @@ describe API::ProjectSnippets do it 'returns 400 for empty code field' do new_content = '' - put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content + put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), params: { code: new_content } expect(response).to have_gitlab_http_status(400) end context 'when the snippet is spam' do def update_snippet(snippet_params = {}) - put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}", admin), snippet_params + put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}", admin), params: snippet_params end before do diff --git a/spec/requests/api/project_templates_spec.rb b/spec/requests/api/project_templates_spec.rb index 86e33f23951..ab5d4de7ff7 100644 --- a/spec/requests/api/project_templates_spec.rb +++ b/spec/requests/api/project_templates_spec.rb @@ -130,8 +130,10 @@ describe API::ProjectTemplates do describe 'GET /projects/:id/templates/licenses/:key' do it 'fills placeholders in the license' do get api("/projects/#{public_project.id}/templates/licenses/agpl-3.0"), - project: 'Project Placeholder', - fullname: 'Fullname Placeholder' + params: { + project: 'Project Placeholder', + fullname: 'Fullname Placeholder' + } expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('public_api/v4/license') diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index e40db55cd20..ffe4512fa6f 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -52,7 +52,7 @@ describe API::Projects do describe 'GET /projects' do shared_examples_for 'projects response' do it 'returns an array of projects' do - get api('/projects', current_user), filter + get api('/projects', current_user), params: filter expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -61,7 +61,7 @@ describe API::Projects do end it 'returns the proper security headers' do - get api('/projects', current_user), filter + get api('/projects', current_user), params: filter expect(response).to include_security_headers end @@ -192,7 +192,7 @@ describe API::Projects do end it "includes statistics if requested" do - get api('/projects', user), statistics: true + get api('/projects', user), params: { statistics: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -210,7 +210,7 @@ describe API::Projects do end it "does not include license if requested" do - get api('/projects', user), license: true + get api('/projects', user), params: { license: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -315,7 +315,7 @@ describe API::Projects do context 'and using the visibility filter' do it 'filters based on private visibility param' do - get api('/projects', user), { visibility: 'private' } + get api('/projects', user), params: { visibility: 'private' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -326,7 +326,7 @@ describe API::Projects do it 'filters based on internal visibility param' do project2.update_attribute(:visibility_level, Gitlab::VisibilityLevel::INTERNAL) - get api('/projects', user), { visibility: 'internal' } + get api('/projects', user), params: { visibility: 'internal' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -335,7 +335,7 @@ describe API::Projects do end it 'filters based on public visibility param' do - get api('/projects', user), { visibility: 'public' } + get api('/projects', user), params: { visibility: 'public' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -346,7 +346,7 @@ describe API::Projects do context 'and using sorting' do it 'returns the correct order when sorted by id' do - get api('/projects', user), { order_by: 'id', sort: 'desc' } + get api('/projects', user), params: { order_by: 'id', sort: 'desc' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -357,7 +357,7 @@ describe API::Projects do context 'and with owned=true' do it 'returns an array of projects the user owns' do - get api('/projects', user4), owned: true + get api('/projects', user4), params: { owned: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -376,7 +376,7 @@ describe API::Projects do end it 'returns the starred projects viewable by the user' do - get api('/projects', user3), starred: true + get api('/projects', user3), params: { starred: true } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -398,7 +398,7 @@ describe API::Projects do context 'including owned filter' do it 'returns only projects that satisfy all query parameters' do - get api('/projects', user), { visibility: 'public', owned: true, starred: true, search: 'gitlab' } + get api('/projects', user), params: { visibility: 'public', owned: true, starred: true, search: 'gitlab' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -417,7 +417,7 @@ describe API::Projects do end it 'returns only projects that satisfy all query parameters' do - get api('/projects', user), { visibility: 'public', membership: true, starred: true, search: 'gitlab' } + get api('/projects', user), params: { visibility: 'public', membership: true, starred: true, search: 'gitlab' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -436,7 +436,7 @@ describe API::Projects do end it 'returns an array of groups the user has at least developer access' do - get api('/projects', user2), { min_access_level: 30 } + get api('/projects', user2), params: { min_access_level: 30 } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_an Array @@ -479,14 +479,14 @@ describe API::Projects do context 'maximum number of projects reached' do it 'does not create new project and respond with 403' do allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0) - expect { post api('/projects', user2), name: 'foo' } + expect { post api('/projects', user2), params: { name: 'foo' } } .to change {Project.count}.by(0) expect(response).to have_gitlab_http_status(403) end end it 'creates new project without path but with name and returns 201' do - expect { post api('/projects', user), name: 'Foo Project' } + expect { post api('/projects', user), params: { name: 'Foo Project' } } .to change { Project.count }.by(1) expect(response).to have_gitlab_http_status(201) @@ -497,7 +497,7 @@ describe API::Projects do end it 'creates new project without name but with path and returns 201' do - expect { post api('/projects', user), path: 'foo_project' } + expect { post api('/projects', user), params: { path: 'foo_project' } } .to change { Project.count }.by(1) expect(response).to have_gitlab_http_status(201) @@ -508,7 +508,7 @@ describe API::Projects do end it 'creates new project with name and path and returns 201' do - expect { post api('/projects', user), path: 'path-project-Foo', name: 'Foo Project' } + expect { post api('/projects', user), params: { path: 'path-project-Foo', name: 'Foo Project' } } .to change { Project.count }.by(1) expect(response).to have_gitlab_http_status(201) @@ -520,7 +520,7 @@ describe API::Projects do it 'creates last project before reaching project limit' do allow_any_instance_of(User).to receive(:projects_limit_left).and_return(1) - post api('/projects', user2), name: 'foo' + post api('/projects', user2), params: { name: 'foo' } expect(response).to have_gitlab_http_status(201) end @@ -544,7 +544,7 @@ describe API::Projects do merge_method: 'ff' }) - post api('/projects', user), project + post api('/projects', user), params: project expect(response).to have_gitlab_http_status(201) @@ -564,7 +564,7 @@ describe API::Projects do it 'sets a project as public' do project = attributes_for(:project, visibility: 'public') - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['visibility']).to eq('public') end @@ -572,7 +572,7 @@ describe API::Projects do it 'sets a project as internal' do project = attributes_for(:project, visibility: 'internal') - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['visibility']).to eq('internal') end @@ -580,7 +580,7 @@ describe API::Projects do it 'sets a project as private' do project = attributes_for(:project, visibility: 'private') - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['visibility']).to eq('private') end @@ -588,7 +588,7 @@ describe API::Projects do it 'creates a new project initialized with a README.md' do project = attributes_for(:project, initialize_with_readme: 1, name: 'somewhere') - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['readme_url']).to eql("#{Gitlab.config.gitlab.url}/#{json_response['namespace']['full_path']}/somewhere/blob/master/README.md") end @@ -596,7 +596,7 @@ describe API::Projects do it 'sets tag list to a project' do project = attributes_for(:project, tag_list: %w[tagFirst tagSecond]) - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['tag_list']).to eq(%w[tagFirst tagSecond]) end @@ -604,7 +604,7 @@ describe API::Projects do it 'uploads avatar for project a project' do project = attributes_for(:project, avatar: fixture_file_upload('spec/fixtures/banana_sample.gif', 'image/gif')) - post api('/projects', user), project + post api('/projects', user), params: project project_id = json_response['id'] expect(json_response['avatar_url']).to eq("http://localhost/uploads/-/system/project/avatar/#{project_id}/banana_sample.gif") @@ -613,7 +613,7 @@ describe API::Projects do it 'sets a project as not allowing outdated diff discussions to automatically resolve' do project = attributes_for(:project, resolve_outdated_diff_discussions: false) - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['resolve_outdated_diff_discussions']).to be_falsey end @@ -621,7 +621,7 @@ describe API::Projects do it 'sets a project as allowing outdated diff discussions to automatically resolve' do project = attributes_for(:project, resolve_outdated_diff_discussions: true) - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['resolve_outdated_diff_discussions']).to be_truthy end @@ -629,7 +629,7 @@ describe API::Projects do it 'sets a project as allowing merge even if build fails' do project = attributes_for(:project, only_allow_merge_if_pipeline_succeeds: false) - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['only_allow_merge_if_pipeline_succeeds']).to be_falsey end @@ -637,7 +637,7 @@ describe API::Projects do it 'sets a project as allowing merge only if merge_when_pipeline_succeeds' do project = attributes_for(:project, only_allow_merge_if_pipeline_succeeds: true) - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['only_allow_merge_if_pipeline_succeeds']).to be_truthy end @@ -645,7 +645,7 @@ describe API::Projects do it 'sets a project as allowing merge even if discussions are unresolved' do project = attributes_for(:project, only_allow_merge_if_all_discussions_are_resolved: false) - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_falsey end @@ -653,7 +653,7 @@ describe API::Projects do it 'sets a project as allowing merge if only_allow_merge_if_all_discussions_are_resolved is nil' do project = attributes_for(:project, only_allow_merge_if_all_discussions_are_resolved: nil) - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_falsey end @@ -661,7 +661,7 @@ describe API::Projects do it 'sets a project as allowing merge only if all discussions are resolved' do project = attributes_for(:project, only_allow_merge_if_all_discussions_are_resolved: true) - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_truthy end @@ -669,7 +669,7 @@ describe API::Projects do it 'sets the merge method of a project to rebase merge' do project = attributes_for(:project, merge_method: 'rebase_merge') - post api('/projects', user), project + post api('/projects', user), params: project expect(json_response['merge_method']).to eq('rebase_merge') end @@ -677,7 +677,7 @@ describe API::Projects do it 'rejects invalid values for merge_method' do project = attributes_for(:project, merge_method: 'totally_not_valid_method') - post api('/projects', user), project + post api('/projects', user), params: project expect(response).to have_gitlab_http_status(400) end @@ -685,7 +685,7 @@ describe API::Projects do it 'ignores import_url when it is nil' do project = attributes_for(:project, import_url: nil) - post api('/projects', user), project + post api('/projects', user), params: project expect(response).to have_gitlab_http_status(201) end @@ -698,7 +698,7 @@ describe API::Projects do end it 'does not allow a non-admin to use a restricted visibility level' do - post api('/projects', user), project_param + post api('/projects', user), params: project_param expect(response).to have_gitlab_http_status(400) expect(json_response['message']['visibility_level'].first).to( @@ -707,7 +707,7 @@ describe API::Projects do end it 'allows an admin to override restricted visibility settings' do - post api('/projects', admin), project_param + post api('/projects', admin), params: project_param expect(json_response['visibility']).to eq('public') end @@ -739,7 +739,7 @@ describe API::Projects do private_project1.add_developer(user2) private_project2.add_reporter(user2) - get api("/users/#{user4.id}/projects/", user2), { min_access_level: 30 } + get api("/users/#{user4.id}/projects/", user2), params: { min_access_level: 30 } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -750,7 +750,7 @@ describe API::Projects do describe 'POST /projects/user/:id' do it 'creates new project without path but with name and return 201' do - expect { post api("/projects/user/#{user.id}", admin), name: 'Foo Project' }.to change { Project.count }.by(1) + expect { post api("/projects/user/#{user.id}", admin), params: { name: 'Foo Project' } }.to change { Project.count }.by(1) expect(response).to have_gitlab_http_status(201) project = Project.last @@ -760,7 +760,7 @@ describe API::Projects do end it 'creates new project with name and path and returns 201' do - expect { post api("/projects/user/#{user.id}", admin), path: 'path-project-Foo', name: 'Foo Project' } + expect { post api("/projects/user/#{user.id}", admin), params: { path: 'path-project-Foo', name: 'Foo Project' } } .to change { Project.count }.by(1) expect(response).to have_gitlab_http_status(201) @@ -787,7 +787,7 @@ describe API::Projects do jobs_enabled: true }) - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(response).to have_gitlab_http_status(201) @@ -801,7 +801,7 @@ describe API::Projects do it 'sets a project as public' do project = attributes_for(:project, visibility: 'public') - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(response).to have_gitlab_http_status(201) expect(json_response['visibility']).to eq('public') @@ -810,7 +810,7 @@ describe API::Projects do it 'sets a project as internal' do project = attributes_for(:project, visibility: 'internal') - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(response).to have_gitlab_http_status(201) expect(json_response['visibility']).to eq('internal') @@ -819,7 +819,7 @@ describe API::Projects do it 'sets a project as private' do project = attributes_for(:project, visibility: 'private') - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(json_response['visibility']).to eq('private') end @@ -827,7 +827,7 @@ describe API::Projects do it 'sets a project as not allowing outdated diff discussions to automatically resolve' do project = attributes_for(:project, resolve_outdated_diff_discussions: false) - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(json_response['resolve_outdated_diff_discussions']).to be_falsey end @@ -835,27 +835,27 @@ describe API::Projects do it 'sets a project as allowing outdated diff discussions to automatically resolve' do project = attributes_for(:project, resolve_outdated_diff_discussions: true) - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(json_response['resolve_outdated_diff_discussions']).to be_truthy end it 'sets a project as allowing merge even if build fails' do project = attributes_for(:project, only_allow_merge_if_pipeline_succeeds: false) - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(json_response['only_allow_merge_if_pipeline_succeeds']).to be_falsey end it 'sets a project as allowing merge only if pipeline succeeds' do project = attributes_for(:project, only_allow_merge_if_pipeline_succeeds: true) - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(json_response['only_allow_merge_if_pipeline_succeeds']).to be_truthy end it 'sets a project as allowing merge even if discussions are unresolved' do project = attributes_for(:project, only_allow_merge_if_all_discussions_are_resolved: false) - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_falsey end @@ -863,7 +863,7 @@ describe API::Projects do it 'sets a project as allowing merge only if all discussions are resolved' do project = attributes_for(:project, only_allow_merge_if_all_discussions_are_resolved: true) - post api("/projects/user/#{user.id}", admin), project + post api("/projects/user/#{user.id}", admin), params: project expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_truthy end @@ -875,7 +875,7 @@ describe API::Projects do end it "uploads the file and returns its info" do - post api("/projects/#{project.id}/uploads", user), file: fixture_file_upload("spec/fixtures/dk.png", "image/png") + post api("/projects/#{project.id}/uploads", user), params: { file: fixture_file_upload("spec/fixtures/dk.png", "image/png") } expect(response).to have_gitlab_http_status(201) expect(json_response['alt']).to eq("dk") @@ -1020,7 +1020,7 @@ describe API::Projects do end it 'includes license fields when requested' do - get api("/projects/#{project.id}", user), license: true + get api("/projects/#{project.id}", user), params: { license: true } expect(response).to have_gitlab_http_status(200) expect(json_response['license']).to eq({ @@ -1040,7 +1040,7 @@ describe API::Projects do end it "includes statistics if requested" do - get api("/projects/#{project.id}", user), statistics: true + get api("/projects/#{project.id}", user), params: { statistics: true } expect(response).to have_gitlab_http_status(200) expect(json_response).to include 'statistics' @@ -1397,7 +1397,7 @@ describe API::Projects do expires_at = 10.days.from_now.to_date expect do - post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER, expires_at: expires_at + post api("/projects/#{project.id}/share", user), params: { group_id: group.id, group_access: Gitlab::Access::DEVELOPER, expires_at: expires_at } end.to change { ProjectGroupLink.count }.by(1) expect(response).to have_gitlab_http_status(201) @@ -1407,37 +1407,37 @@ describe API::Projects do end it "returns a 400 error when group id is not given" do - post api("/projects/#{project.id}/share", user), group_access: Gitlab::Access::DEVELOPER + post api("/projects/#{project.id}/share", user), params: { group_access: Gitlab::Access::DEVELOPER } expect(response).to have_gitlab_http_status(400) end it "returns a 400 error when access level is not given" do - post api("/projects/#{project.id}/share", user), group_id: group.id + post api("/projects/#{project.id}/share", user), params: { group_id: group.id } expect(response).to have_gitlab_http_status(400) end it "returns a 400 error when sharing is disabled" do project.namespace.update(share_with_group_lock: true) - post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER + post api("/projects/#{project.id}/share", user), params: { group_id: group.id, group_access: Gitlab::Access::DEVELOPER } expect(response).to have_gitlab_http_status(400) end it 'returns a 404 error when user cannot read group' do private_group = create(:group, :private) - post api("/projects/#{project.id}/share", user), group_id: private_group.id, group_access: Gitlab::Access::DEVELOPER + post api("/projects/#{project.id}/share", user), params: { group_id: private_group.id, group_access: Gitlab::Access::DEVELOPER } expect(response).to have_gitlab_http_status(404) end it 'returns a 404 error when group does not exist' do - post api("/projects/#{project.id}/share", user), group_id: 1234, group_access: Gitlab::Access::DEVELOPER + post api("/projects/#{project.id}/share", user), params: { group_id: 1234, group_access: Gitlab::Access::DEVELOPER } expect(response).to have_gitlab_http_status(404) end it "returns a 400 error when wrong params passed" do - post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: 1234 + post api("/projects/#{project.id}/share", user), params: { group_id: group.id, group_access: 1234 } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq 'group_access does not have a valid value' @@ -1498,7 +1498,7 @@ describe API::Projects do it 'returns 400 when nothing sent' do project_param = {} - put api("/projects/#{project.id}", user), project_param + put api("/projects/#{project.id}", user), params: project_param expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to match('at least one parameter must be provided') @@ -1508,7 +1508,7 @@ describe API::Projects do it 'returns authentication error' do project_param = { name: 'bar' } - put api("/projects/#{project.id}"), project_param + put api("/projects/#{project.id}"), params: project_param expect(response).to have_gitlab_http_status(401) end @@ -1518,7 +1518,7 @@ describe API::Projects do it 'updates name' do project_param = { name: 'bar' } - put api("/projects/#{project.id}", user), project_param + put api("/projects/#{project.id}", user), params: project_param expect(response).to have_gitlab_http_status(200) @@ -1530,7 +1530,7 @@ describe API::Projects do it 'updates visibility_level' do project_param = { visibility: 'public' } - put api("/projects/#{project3.id}", user), project_param + put api("/projects/#{project3.id}", user), params: project_param expect(response).to have_gitlab_http_status(200) @@ -1543,7 +1543,7 @@ describe API::Projects do project3.update({ visibility_level: Gitlab::VisibilityLevel::PUBLIC }) project_param = { visibility: 'private' } - put api("/projects/#{project3.id}", user), project_param + put api("/projects/#{project3.id}", user), params: project_param expect(response).to have_gitlab_http_status(200) @@ -1557,7 +1557,7 @@ describe API::Projects do it 'does not update name to existing name' do project_param = { name: project3.name } - put api("/projects/#{project.id}", user), project_param + put api("/projects/#{project.id}", user), params: project_param expect(response).to have_gitlab_http_status(400) expect(json_response['message']['name']).to eq(['has already been taken']) @@ -1566,7 +1566,7 @@ describe API::Projects do it 'updates request_access_enabled' do project_param = { request_access_enabled: false } - put api("/projects/#{project.id}", user), project_param + put api("/projects/#{project.id}", user), params: project_param expect(response).to have_gitlab_http_status(200) expect(json_response['request_access_enabled']).to eq(false) @@ -1575,7 +1575,7 @@ describe API::Projects do it 'updates path & name to existing path & name in different namespace' do project_param = { path: project4.path, name: project4.name } - put api("/projects/#{project3.id}", user), project_param + put api("/projects/#{project3.id}", user), params: project_param expect(response).to have_gitlab_http_status(200) @@ -1587,7 +1587,7 @@ describe API::Projects do it 'updates jobs_enabled' do project_param = { jobs_enabled: true } - put api("/projects/#{project3.id}", user), project_param + put api("/projects/#{project3.id}", user), params: project_param expect(response).to have_gitlab_http_status(200) @@ -1599,7 +1599,7 @@ describe API::Projects do it 'updates merge_method' do project_param = { merge_method: 'ff' } - put api("/projects/#{project3.id}", user), project_param + put api("/projects/#{project3.id}", user), params: project_param expect(response).to have_gitlab_http_status(200) @@ -1611,7 +1611,7 @@ describe API::Projects do it 'rejects to update merge_method when merge_method is invalid' do project_param = { merge_method: 'invalid' } - put api("/projects/#{project3.id}", user), project_param + put api("/projects/#{project3.id}", user), params: project_param expect(response).to have_gitlab_http_status(400) end @@ -1622,7 +1622,7 @@ describe API::Projects do 'image/gif') } - put api("/projects/#{project3.id}", user), project_param + put api("/projects/#{project3.id}", user), params: project_param expect(response).to have_gitlab_http_status(200) expect(json_response['avatar_url']).to eq('http://localhost/uploads/'\ @@ -1634,7 +1634,7 @@ describe API::Projects do context 'when authenticated as project maintainer' do it 'updates path' do project_param = { path: 'bar' } - put api("/projects/#{project3.id}", user4), project_param + put api("/projects/#{project3.id}", user4), params: project_param expect(response).to have_gitlab_http_status(200) project_param.each_pair do |k, v| expect(json_response[k.to_s]).to eq(v) @@ -1649,7 +1649,7 @@ describe API::Projects do merge_method: 'ff', description: 'new description' } - put api("/projects/#{project3.id}", user4), project_param + put api("/projects/#{project3.id}", user4), params: project_param expect(response).to have_gitlab_http_status(200) project_param.each_pair do |k, v| expect(json_response[k.to_s]).to eq(v) @@ -1658,20 +1658,20 @@ describe API::Projects do it 'does not update path to existing path' do project_param = { path: project.path } - put api("/projects/#{project3.id}", user4), project_param + put api("/projects/#{project3.id}", user4), params: project_param expect(response).to have_gitlab_http_status(400) expect(json_response['message']['path']).to eq(['has already been taken']) end it 'does not update name' do project_param = { name: 'bar' } - put api("/projects/#{project3.id}", user4), project_param + put api("/projects/#{project3.id}", user4), params: project_param expect(response).to have_gitlab_http_status(403) end it 'does not update visibility_level' do project_param = { visibility: 'public' } - put api("/projects/#{project3.id}", user4), project_param + put api("/projects/#{project3.id}", user4), params: project_param expect(response).to have_gitlab_http_status(403) end end @@ -1685,7 +1685,7 @@ describe API::Projects do merge_requests_enabled: true, description: 'new description', request_access_enabled: true } - put api("/projects/#{project.id}", user3), project_param + put api("/projects/#{project.id}", user3), params: project_param expect(response).to have_gitlab_http_status(403) end end @@ -1971,41 +1971,41 @@ describe API::Projects do end it 'forks with explicit own user namespace id' do - post api("/projects/#{project.id}/fork", user2), namespace: user2.namespace.id + post api("/projects/#{project.id}/fork", user2), params: { namespace: user2.namespace.id } expect(response).to have_gitlab_http_status(201) expect(json_response['owner']['id']).to eq(user2.id) end it 'forks with explicit own user name as namespace' do - post api("/projects/#{project.id}/fork", user2), namespace: user2.username + post api("/projects/#{project.id}/fork", user2), params: { namespace: user2.username } expect(response).to have_gitlab_http_status(201) expect(json_response['owner']['id']).to eq(user2.id) end it 'forks to another user when admin' do - post api("/projects/#{project.id}/fork", admin), namespace: user2.username + post api("/projects/#{project.id}/fork", admin), params: { namespace: user2.username } expect(response).to have_gitlab_http_status(201) expect(json_response['owner']['id']).to eq(user2.id) end it 'fails if trying to fork to another user when not admin' do - post api("/projects/#{project.id}/fork", user2), namespace: admin.namespace.id + post api("/projects/#{project.id}/fork", user2), params: { namespace: admin.namespace.id } expect(response).to have_gitlab_http_status(404) end it 'fails if trying to fork to non-existent namespace' do - post api("/projects/#{project.id}/fork", user2), namespace: 42424242 + post api("/projects/#{project.id}/fork", user2), params: { namespace: 42424242 } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Target Namespace Not Found') end it 'forks to owned group' do - post api("/projects/#{project.id}/fork", user2), namespace: group2.name + post api("/projects/#{project.id}/fork", user2), params: { namespace: group2.name } expect(response).to have_gitlab_http_status(201) expect(json_response['namespace']['name']).to eq(group2.name) @@ -2013,7 +2013,7 @@ describe API::Projects do it 'forks to owned subgroup' do full_path = "#{group2.path}/#{group3.path}" - post api("/projects/#{project.id}/fork", user2), namespace: full_path + post api("/projects/#{project.id}/fork", user2), params: { namespace: full_path } expect(response).to have_gitlab_http_status(201) expect(json_response['namespace']['name']).to eq(group3.name) @@ -2021,13 +2021,13 @@ describe API::Projects do end it 'fails to fork to not owned group' do - post api("/projects/#{project.id}/fork", user2), namespace: group.name + post api("/projects/#{project.id}/fork", user2), params: { namespace: group.name } expect(response).to have_gitlab_http_status(404) end it 'forks to not owned group when admin' do - post api("/projects/#{project.id}/fork", admin), namespace: group.name + post api("/projects/#{project.id}/fork", admin), params: { namespace: group.name } expect(response).to have_gitlab_http_status(201) expect(json_response['namespace']['name']).to eq(group.name) @@ -2100,19 +2100,19 @@ describe API::Projects do it 'transfers the project to the new namespace' do group.add_owner(user) - put api("/projects/#{project.id}/transfer", user), namespace: group.id + put api("/projects/#{project.id}/transfer", user), params: { namespace: group.id } expect(response).to have_gitlab_http_status(200) end it 'fails when transferring to a non owned namespace' do - put api("/projects/#{project.id}/transfer", user), namespace: group.id + put api("/projects/#{project.id}/transfer", user), params: { namespace: group.id } expect(response).to have_gitlab_http_status(404) end it 'fails when transferring to an unknown namespace' do - put api("/projects/#{project.id}/transfer", user), namespace: 'unknown' + put api("/projects/#{project.id}/transfer", user), params: { namespace: 'unknown' } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/requests/api/protected_branches_spec.rb b/spec/requests/api/protected_branches_spec.rb index 69a601d7b40..f90558d77a9 100644 --- a/spec/requests/api/protected_branches_spec.rb +++ b/spec/requests/api/protected_branches_spec.rb @@ -14,7 +14,7 @@ describe API::ProtectedBranches do shared_examples_for 'protected branches' do it 'returns the protected branches' do - get api(route, user), per_page: 100 + get api(route, user), params: { per_page: 100 } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -114,7 +114,7 @@ describe API::ProtectedBranches do end it 'protects a single branch' do - post post_endpoint, name: branch_name + post post_endpoint, params: { name: branch_name } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(branch_name) @@ -123,7 +123,7 @@ describe API::ProtectedBranches do end it 'protects a single branch and developers can push' do - post post_endpoint, name: branch_name, push_access_level: 30 + post post_endpoint, params: { name: branch_name, push_access_level: 30 } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(branch_name) @@ -132,7 +132,7 @@ describe API::ProtectedBranches do end it 'protects a single branch and developers can merge' do - post post_endpoint, name: branch_name, merge_access_level: 30 + post post_endpoint, params: { name: branch_name, merge_access_level: 30 } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(branch_name) @@ -141,7 +141,7 @@ describe API::ProtectedBranches do end it 'protects a single branch and developers can push and merge' do - post post_endpoint, name: branch_name, push_access_level: 30, merge_access_level: 30 + post post_endpoint, params: { name: branch_name, push_access_level: 30, merge_access_level: 30 } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(branch_name) @@ -150,7 +150,7 @@ describe API::ProtectedBranches do end it 'protects a single branch and no one can push' do - post post_endpoint, name: branch_name, push_access_level: 0 + post post_endpoint, params: { name: branch_name, push_access_level: 0 } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(branch_name) @@ -159,7 +159,7 @@ describe API::ProtectedBranches do end it 'protects a single branch and no one can merge' do - post post_endpoint, name: branch_name, merge_access_level: 0 + post post_endpoint, params: { name: branch_name, merge_access_level: 0 } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(branch_name) @@ -168,7 +168,7 @@ describe API::ProtectedBranches do end it 'protects a single branch and no one can push or merge' do - post post_endpoint, name: branch_name, push_access_level: 0, merge_access_level: 0 + post post_endpoint, params: { name: branch_name, push_access_level: 0, merge_access_level: 0 } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(branch_name) @@ -177,7 +177,7 @@ describe API::ProtectedBranches do end it 'returns a 409 error if the same branch is protected twice' do - post post_endpoint, name: protected_name + post post_endpoint, params: { name: protected_name } expect(response).to have_gitlab_http_status(409) end @@ -186,7 +186,7 @@ describe API::ProtectedBranches do let(:branch_name) { 'feature/*' } it "protects multiple branches with a wildcard in the name" do - post post_endpoint, name: branch_name + post post_endpoint, params: { name: branch_name } expect_protection_to_be_successful expect(json_response['push_access_levels'][0]['access_level']).to eq(Gitlab::Access::MAINTAINER) @@ -201,7 +201,7 @@ describe API::ProtectedBranches do end it "prevents deletion of the protected branch rule" do - post post_endpoint, name: branch_name + post post_endpoint, params: { name: branch_name } expect(response).to have_gitlab_http_status(403) end @@ -214,7 +214,7 @@ describe API::ProtectedBranches do end it "returns a 403 error if guest" do - post post_endpoint, name: branch_name + post post_endpoint, params: { name: branch_name } expect(response).to have_gitlab_http_status(403) end diff --git a/spec/requests/api/protected_tags_spec.rb b/spec/requests/api/protected_tags_spec.rb index f4f3ef31bc3..41363dcc1c3 100644 --- a/spec/requests/api/protected_tags_spec.rb +++ b/spec/requests/api/protected_tags_spec.rb @@ -15,7 +15,7 @@ describe API::ProtectedTags do shared_examples_for 'protected tags' do it 'returns the protected tags' do - get api(route, user), per_page: 100 + get api(route, user), params: { per_page: 100 } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -102,7 +102,7 @@ describe API::ProtectedTags do end it 'protects a single tag with maintainers can create tags' do - post api("/projects/#{project.id}/protected_tags", user), name: tag_name + post api("/projects/#{project.id}/protected_tags", user), params: { name: tag_name } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(tag_name) @@ -111,7 +111,7 @@ describe API::ProtectedTags do it 'protects a single tag with developers can create tags' do post api("/projects/#{project.id}/protected_tags", user), - name: tag_name, create_access_level: 30 + params: { name: tag_name, create_access_level: 30 } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(tag_name) @@ -120,7 +120,7 @@ describe API::ProtectedTags do it 'protects a single tag with no one can create tags' do post api("/projects/#{project.id}/protected_tags", user), - name: tag_name, create_access_level: 0 + params: { name: tag_name, create_access_level: 0 } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(tag_name) @@ -128,15 +128,15 @@ describe API::ProtectedTags do end it 'returns a 422 error if the same tag is protected twice' do - post api("/projects/#{project.id}/protected_tags", user), name: protected_name + post api("/projects/#{project.id}/protected_tags", user), params: { name: protected_name } expect(response).to have_gitlab_http_status(422) expect(json_response['message'][0]).to eq('Name has already been taken') end it 'returns 201 if the same tag is proteted on different projects' do - post api("/projects/#{project.id}/protected_tags", user), name: protected_name - post api("/projects/#{project2.id}/protected_tags", user), name: protected_name + post api("/projects/#{project.id}/protected_tags", user), params: { name: protected_name } + post api("/projects/#{project2.id}/protected_tags", user), params: { name: protected_name } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(protected_name) @@ -146,7 +146,7 @@ describe API::ProtectedTags do let(:tag_name) { 'feature/*' } it 'protects multiple tags with a wildcard in the name' do - post api("/projects/#{project.id}/protected_tags", user), name: tag_name + post api("/projects/#{project.id}/protected_tags", user), params: { name: tag_name } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(tag_name) @@ -161,7 +161,7 @@ describe API::ProtectedTags do end it 'returns a 403 error if guest' do - post api("/projects/#{project.id}/protected_tags/", user), name: tag_name + post api("/projects/#{project.id}/protected_tags/", user), params: { name: tag_name } expect(response).to have_gitlab_http_status(403) end diff --git a/spec/requests/api/redacted_events_spec.rb b/spec/requests/api/redacted_events_spec.rb deleted file mode 100644 index 086dd3df9ba..00000000000 --- a/spec/requests/api/redacted_events_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'spec_helper' - -describe 'Redacted events in API::Events' do - shared_examples 'private events are redacted' do - it 'redacts events the user does not have access to' do - expect_any_instance_of(Event).to receive(:visible_to_user?).and_call_original - - get api(path), user - - expect(response).to have_gitlab_http_status(200) - expect(json_response).to contain_exactly( - 'project_id' => nil, - 'action_name' => nil, - 'target_id' => nil, - 'target_iid' => nil, - 'target_type' => nil, - 'author_id' => nil, - 'target_title' => 'Confidential event', - 'created_at' => nil, - 'author_username' => nil - ) - end - end - - describe '/users/:id/events' do - let(:project) { create(:project, :public) } - let(:path) { "/users/#{project.owner.id}/events" } - let(:issue) { create(:issue, :confidential, project: project) } - - before do - EventCreateService.new.open_issue(issue, issue.author) - end - - context 'unauthenticated user views another user with private events' do - let(:user) { nil } - - include_examples 'private events are redacted' - end - - context 'authenticated user without access views another user with private events' do - let(:user) { create(:user) } - - include_examples 'private events are redacted' - end - end - - describe '/projects/:id/events' do - let(:project) { create(:project, :public) } - let(:path) { "/projects/#{project.id}/events" } - let(:issue) { create(:issue, :confidential, project: project) } - - before do - EventCreateService.new.open_issue(issue, issue.author) - end - - context 'unauthenticated user views public project' do - let(:user) { nil } - - include_examples 'private events are redacted' - end - - context 'authenticated user without access views public project' do - let(:user) { create(:user) } - - include_examples 'private events are redacted' - end - end -end diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb new file mode 100644 index 00000000000..a44e37f9cd5 --- /dev/null +++ b/spec/requests/api/releases_spec.rb @@ -0,0 +1,532 @@ +require 'spec_helper' + +describe API::Releases do + let(:project) { create(:project, :repository, :private) } + let(:maintainer) { create(:user) } + let(:reporter) { create(:user) } + let(:non_project_member) { create(:user) } + let(:commit) { create(:commit, project: project) } + + before do + project.add_maintainer(maintainer) + project.add_reporter(reporter) + + project.repository.add_tag(maintainer, 'v0.1', commit.id) + project.repository.add_tag(maintainer, 'v0.2', commit.id) + end + + describe 'GET /projects/:id/releases' do + context 'when there are two releases' do + let!(:release_1) do + create(:release, + project: project, + tag: 'v0.1', + author: maintainer, + created_at: 2.days.ago) + end + + let!(:release_2) do + create(:release, + project: project, + tag: 'v0.2', + author: maintainer, + created_at: 1.day.ago) + end + + it 'returns 200 HTTP status' do + get api("/projects/#{project.id}/releases", maintainer) + + expect(response).to have_gitlab_http_status(:ok) + end + + it 'returns releases ordered by created_at' do + get api("/projects/#{project.id}/releases", maintainer) + + expect(json_response.count).to eq(2) + expect(json_response.first['tag_name']).to eq(release_2.tag) + expect(json_response.second['tag_name']).to eq(release_1.tag) + end + + it 'matches response schema' do + get api("/projects/#{project.id}/releases", maintainer) + + expect(response).to match_response_schema('releases') + end + end + + context 'when tag does not exist in git repository' do + let!(:release) { create(:release, project: project, tag: 'v1.1.5') } + + it 'returns the tag' do + get api("/projects/#{project.id}/releases", maintainer) + + expect(json_response.count).to eq(1) + expect(json_response.first['tag_name']).to eq('v1.1.5') + expect(release).to be_tag_missing + end + end + + context 'when user is not a project member' do + it 'cannot find the project' do + get api("/projects/#{project.id}/releases", non_project_member) + + expect(response).to have_gitlab_http_status(:not_found) + end + + context 'when project is public' do + let(:project) { create(:project, :repository, :public) } + + it 'allows the request' do + get api("/projects/#{project.id}/releases", non_project_member) + + expect(response).to have_gitlab_http_status(:ok) + end + end + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(releases_page: false) + end + + it 'cannot find the API' do + get api("/projects/#{project.id}/releases", maintainer) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + describe 'GET /projects/:id/releases/:tag_name' do + context 'when there is a release' do + let!(:release) do + create(:release, + project: project, + tag: 'v0.1', + sha: commit.id, + author: maintainer, + description: 'This is v0.1') + end + + it 'returns 200 HTTP status' do + get api("/projects/#{project.id}/releases/v0.1", maintainer) + + expect(response).to have_gitlab_http_status(:ok) + end + + it 'returns a release entry' do + get api("/projects/#{project.id}/releases/v0.1", maintainer) + + expect(json_response['tag_name']).to eq(release.tag) + expect(json_response['description']).to eq('This is v0.1') + expect(json_response['author']['name']).to eq(maintainer.name) + expect(json_response['commit']['id']).to eq(commit.id) + end + + it 'matches response schema' do + get api("/projects/#{project.id}/releases/v0.1", maintainer) + + expect(response).to match_response_schema('release') + end + end + + context 'when specified tag is not found in the project' do + it 'cannot find the release entry' do + get api("/projects/#{project.id}/releases/non_exist_tag", maintainer) + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when user is not a project member' do + let!(:release) { create(:release, tag: 'v0.1', project: project) } + + it 'cannot find the project' do + get api("/projects/#{project.id}/releases/v0.1", non_project_member) + + expect(response).to have_gitlab_http_status(:not_found) + end + + context 'when project is public' do + let(:project) { create(:project, :repository, :public) } + + it 'allows the request' do + get api("/projects/#{project.id}/releases/v0.1", non_project_member) + + expect(response).to have_gitlab_http_status(:ok) + end + end + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(releases_page: false) + end + + it 'cannot find the API' do + get api("/projects/#{project.id}/releases/v0.1", maintainer) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + describe 'POST /projects/:id/releases' do + let(:params) do + { + name: 'New release', + tag_name: 'v0.1', + description: 'Super nice release' + } + end + + it 'accepts the request' do + post api("/projects/#{project.id}/releases", maintainer), params: params + + expect(response).to have_gitlab_http_status(:created) + end + + it 'creates a new release' do + expect do + post api("/projects/#{project.id}/releases", maintainer), params: params + end.to change { Release.count }.by(1) + + expect(project.releases.last.name).to eq('New release') + expect(project.releases.last.tag).to eq('v0.1') + expect(project.releases.last.description).to eq('Super nice release') + end + + context 'when description is empty' do + let(:params) do + { + name: 'New release', + tag_name: 'v0.1', + description: '' + } + end + + it 'returns an error as validation failure' do + expect do + post api("/projects/#{project.id}/releases", maintainer), params: params + end.not_to change { Release.count } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['message']) + .to eq("Validation failed: Description can't be blank") + end + end + + it 'matches response schema' do + post api("/projects/#{project.id}/releases", maintainer), params: params + + expect(response).to match_response_schema('release') + end + + it 'does not create a new tag' do + expect do + post api("/projects/#{project.id}/releases", maintainer), params: params + end.not_to change { Project.find_by_id(project.id).repository.tag_count } + end + + context 'when user is a reporter' do + it 'forbids the request' do + post api("/projects/#{project.id}/releases", reporter), params: params + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when user is not a project member' do + it 'forbids the request' do + post api("/projects/#{project.id}/releases", non_project_member), + params: params + + expect(response).to have_gitlab_http_status(:not_found) + end + + context 'when project is public' do + let(:project) { create(:project, :repository, :public) } + + it 'forbids the request' do + post api("/projects/#{project.id}/releases", non_project_member), + params: params + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + end + + context 'when tag does not exist in git repository' do + let(:params) do + { + name: 'Android ~ Ice Cream Sandwich ~', + tag_name: tag_name, + description: 'Android 4.0–4.0.4 "Ice Cream Sandwich" is the ninth' \ + 'version of the Android mobile operating system developed' \ + 'by Google.', + ref: 'master' + } + end + + let(:tag_name) { 'v4.0' } + + it 'creates a new tag' do + expect do + post api("/projects/#{project.id}/releases", maintainer), params: params + end.to change { Project.find_by_id(project.id).repository.tag_count }.by(1) + + expect(project.repository.find_tag('v4.0').dereferenced_target.id) + .to eq(project.repository.commit('master').id) + end + + it 'creates a new release' do + expect do + post api("/projects/#{project.id}/releases", maintainer), params: params + end.to change { Release.count }.by(1) + + expect(project.releases.last.name).to eq('Android ~ Ice Cream Sandwich ~') + expect(project.releases.last.tag).to eq('v4.0') + expect(project.releases.last.description).to eq( + 'Android 4.0–4.0.4 "Ice Cream Sandwich" is the ninth' \ + 'version of the Android mobile operating system developed' \ + 'by Google.') + end + + context 'when tag name is HEAD' do + let(:tag_name) { 'HEAD' } + + it 'returns an error as failure on tag creation' do + post api("/projects/#{project.id}/releases", maintainer), params: params + + expect(response).to have_gitlab_http_status(:internal_server_error) + expect(json_response['message']).to eq('Tag name invalid') + end + end + + context 'when tag name is empty' do + let(:tag_name) { '' } + + it 'returns an error as failure on tag creation' do + post api("/projects/#{project.id}/releases", maintainer), params: params + + expect(response).to have_gitlab_http_status(:internal_server_error) + expect(json_response['message']).to eq('Tag name invalid') + end + end + end + + context 'when release already exists' do + before do + create(:release, project: project, tag: 'v0.1', name: 'New release') + end + + it 'returns an error as conflicted request' do + post api("/projects/#{project.id}/releases", maintainer), params: params + + expect(response).to have_gitlab_http_status(:conflict) + end + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(releases_page: false) + end + + it 'cannot find the API' do + post api("/projects/#{project.id}/releases", maintainer), params: params + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + describe 'PUT /projects/:id/releases/:tag_name' do + let(:params) { { description: 'Best release ever!' } } + + let!(:release) do + create(:release, + project: project, + tag: 'v0.1', + name: 'New release', + description: 'Super nice release') + end + + it 'accepts the request' do + put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params + + expect(response).to have_gitlab_http_status(:ok) + end + + it 'updates the description' do + put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params + + expect(project.releases.last.description).to eq('Best release ever!') + end + + it 'does not change other attributes' do + put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params + + expect(project.releases.last.tag).to eq('v0.1') + expect(project.releases.last.name).to eq('New release') + end + + it 'matches response schema' do + put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params + + expect(response).to match_response_schema('release') + end + + context 'when user tries to update sha' do + let(:params) { { sha: 'xxx' } } + + it 'does not allow the request' do + put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params + + expect(response).to have_gitlab_http_status(:bad_request) + end + end + + context 'when params is empty' do + let(:params) { {} } + + it 'does not allow the request' do + put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params + + expect(response).to have_gitlab_http_status(:bad_request) + end + end + + context 'when there are no corresponding releases' do + let!(:release) { } + + it 'forbids the request' do + put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when user is a reporter' do + it 'forbids the request' do + put api("/projects/#{project.id}/releases/v0.1", reporter), params: params + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when user is not a project member' do + it 'forbids the request' do + put api("/projects/#{project.id}/releases/v0.1", non_project_member), + params: params + + expect(response).to have_gitlab_http_status(:not_found) + end + + context 'when project is public' do + let(:project) { create(:project, :repository, :public) } + + it 'forbids the request' do + put api("/projects/#{project.id}/releases/v0.1", non_project_member), + params: params + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(releases_page: false) + end + + it 'cannot find the API' do + put api("/projects/#{project.id}/releases/v0.1", non_project_member), + params: params + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + describe 'DELETE /projects/:id/releases/:tag_name' do + let!(:release) do + create(:release, + project: project, + tag: 'v0.1', + name: 'New release', + description: 'Super nice release') + end + + it 'accepts the request' do + delete api("/projects/#{project.id}/releases/v0.1", maintainer) + + expect(response).to have_gitlab_http_status(:ok) + end + + it 'destroys the release' do + expect do + delete api("/projects/#{project.id}/releases/v0.1", maintainer) + end.to change { Release.count }.by(-1) + end + + it 'does not remove a tag in repository' do + expect do + delete api("/projects/#{project.id}/releases/v0.1", maintainer) + end.not_to change { Project.find_by_id(project.id).repository.tag_count } + end + + it 'matches response schema' do + delete api("/projects/#{project.id}/releases/v0.1", maintainer) + + expect(response).to match_response_schema('release') + end + + context 'when there are no corresponding releases' do + let!(:release) { } + + it 'forbids the request' do + delete api("/projects/#{project.id}/releases/v0.1", maintainer) + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when user is a reporter' do + it 'forbids the request' do + delete api("/projects/#{project.id}/releases/v0.1", reporter) + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when user is not a project member' do + it 'forbids the request' do + delete api("/projects/#{project.id}/releases/v0.1", non_project_member) + + expect(response).to have_gitlab_http_status(:not_found) + end + + context 'when project is public' do + let(:project) { create(:project, :repository, :public) } + + it 'forbids the request' do + delete api("/projects/#{project.id}/releases/v0.1", non_project_member) + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(releases_page: false) + end + + it 'cannot find the API' do + delete api("/projects/#{project.id}/releases/v0.1", non_project_member) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end +end diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index de141377793..b6b57803a6a 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -171,7 +171,7 @@ describe API::Repositories do it 'forces attachment content disposition' do get api(route, current_user) - expect(headers['Content-Disposition']).to match(/^attachment/) + expect(headers['Content-Disposition']).to eq 'attachment' end context 'when sha does not exist' do @@ -297,7 +297,7 @@ describe API::Repositories do expect(::Gitlab::Git::Compare).to receive(:new).with(anything, anything, anything, { straight: false }).and_call_original - get api(route, current_user), from: 'master', to: 'feature' + get api(route, current_user), params: { from: 'master', to: 'feature' } expect(response).to have_gitlab_http_status(200) expect(json_response['commits']).to be_present @@ -308,7 +308,7 @@ describe API::Repositories do expect(::Gitlab::Git::Compare).to receive(:new).with(anything, anything, anything, { straight: false }).and_call_original - get api(route, current_user), from: 'master', to: 'feature', straight: false + get api(route, current_user), params: { from: 'master', to: 'feature', straight: false } expect(response).to have_gitlab_http_status(200) expect(json_response['commits']).to be_present @@ -319,7 +319,7 @@ describe API::Repositories do expect(::Gitlab::Git::Compare).to receive(:new).with(anything, anything, anything, { straight: true }).and_call_original - get api(route, current_user), from: 'master', to: 'feature', straight: true + get api(route, current_user), params: { from: 'master', to: 'feature', straight: true } expect(response).to have_gitlab_http_status(200) expect(json_response['commits']).to be_present @@ -327,7 +327,7 @@ describe API::Repositories do end it "compares tags" do - get api(route, current_user), from: 'v1.0.0', to: 'v1.1.0' + get api(route, current_user), params: { from: 'v1.0.0', to: 'v1.1.0' } expect(response).to have_gitlab_http_status(200) expect(json_response['commits']).to be_present @@ -335,7 +335,7 @@ describe API::Repositories do end it "compares commits" do - get api(route, current_user), from: sample_commit.id, to: sample_commit.parent_id + get api(route, current_user), params: { from: sample_commit.id, to: sample_commit.parent_id } expect(response).to have_gitlab_http_status(200) expect(json_response['commits']).to be_empty @@ -344,7 +344,7 @@ describe API::Repositories do end it "compares commits in reverse order" do - get api(route, current_user), from: sample_commit.parent_id, to: sample_commit.id + get api(route, current_user), params: { from: sample_commit.parent_id, to: sample_commit.id } expect(response).to have_gitlab_http_status(200) expect(json_response['commits']).to be_present @@ -352,7 +352,7 @@ describe API::Repositories do end it "compares same refs" do - get api(route, current_user), from: 'master', to: 'master' + get api(route, current_user), params: { from: 'master', to: 'master' } expect(response).to have_gitlab_http_status(200) expect(json_response['commits']).to be_empty @@ -410,7 +410,7 @@ describe API::Repositories do context 'using sorting' do context 'by commits desc' do it 'returns the repository contribuors sorted by commits desc' do - get api(route, current_user), { order_by: 'commits', sort: 'desc' } + get api(route, current_user), params: { order_by: 'commits', sort: 'desc' } expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('contributors') @@ -420,7 +420,7 @@ describe API::Repositories do context 'by name desc' do it 'returns the repository contribuors sorted by name asc case insensitive' do - get api(route, current_user), { order_by: 'name', sort: 'asc' } + get api(route, current_user), params: { order_by: 'name', sort: 'asc' } expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('contributors') @@ -478,7 +478,7 @@ describe API::Repositories do end subject(:request) do - get(api("/projects/#{project.id}/repository/merge_base", current_user), refs: refs) + get(api("/projects/#{project.id}/repository/merge_base", current_user), params: { refs: refs }) end shared_examples 'merge base' do diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb index b36087b86a7..c63621fe7d1 100644 --- a/spec/requests/api/runner_spec.rb +++ b/spec/requests/api/runner_spec.rb @@ -25,7 +25,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when invalid token is provided' do it 'returns 403 error' do - post api('/runners'), token: 'invalid' + post api('/runners'), params: { token: 'invalid' } expect(response).to have_gitlab_http_status 403 end @@ -33,7 +33,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when valid token is provided' do it 'creates runner with default values' do - post api('/runners'), token: registration_token + post api('/runners'), params: { token: registration_token } runner = Ci::Runner.first @@ -50,7 +50,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:project) { create(:project) } it 'creates project runner' do - post api('/runners'), token: project.runners_token + post api('/runners'), params: { token: project.runners_token } expect(response).to have_gitlab_http_status 201 expect(project.runners.size).to eq(1) @@ -65,7 +65,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:group) { create(:group) } it 'creates a group runner' do - post api('/runners'), token: group.runners_token + post api('/runners'), params: { token: group.runners_token } expect(response).to have_http_status 201 expect(group.runners.size).to eq(1) @@ -79,8 +79,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when runner description is provided' do it 'creates runner' do - post api('/runners'), token: registration_token, - description: 'server.hostname' + post api('/runners'), params: { + token: registration_token, + description: 'server.hostname' + } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.description).to eq('server.hostname') @@ -89,8 +91,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when runner tags are provided' do it 'creates runner' do - post api('/runners'), token: registration_token, - tag_list: 'tag1, tag2' + post api('/runners'), params: { + token: registration_token, + tag_list: 'tag1, tag2' + } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.tag_list.sort).to eq(%w(tag1 tag2)) @@ -100,9 +104,11 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when option for running untagged jobs is provided' do context 'when tags are provided' do it 'creates runner' do - post api('/runners'), token: registration_token, - run_untagged: false, - tag_list: ['tag'] + post api('/runners'), params: { + token: registration_token, + run_untagged: false, + tag_list: ['tag'] + } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.run_untagged).to be false @@ -112,8 +118,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when tags are not provided' do it 'returns 400 error' do - post api('/runners'), token: registration_token, - run_untagged: false + post api('/runners'), params: { + token: registration_token, + run_untagged: false + } expect(response).to have_gitlab_http_status 400 expect(json_response['message']).to include( @@ -124,8 +132,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when option for locking Runner is provided' do it 'creates runner' do - post api('/runners'), token: registration_token, - locked: true + post api('/runners'), params: { + token: registration_token, + locked: true + } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.locked).to be true @@ -135,8 +145,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when option for activating a Runner is provided' do context 'when active is set to true' do it 'creates runner' do - post api('/runners'), token: registration_token, - active: true + post api('/runners'), params: { + token: registration_token, + active: true + } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.active).to be true @@ -145,8 +157,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when active is set to false' do it 'creates runner' do - post api('/runners'), token: registration_token, - active: false + post api('/runners'), params: { + token: registration_token, + active: false + } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.active).to be false @@ -156,8 +170,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when maximum job timeout is specified' do it 'creates runner' do - post api('/runners'), token: registration_token, - maximum_timeout: 9000 + post api('/runners'), params: { + token: registration_token, + maximum_timeout: 9000 + } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.maximum_timeout).to eq(9000) @@ -165,8 +181,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when maximum job timeout is empty' do it 'creates runner' do - post api('/runners'), token: registration_token, - maximum_timeout: '' + post api('/runners'), params: { + token: registration_token, + maximum_timeout: '' + } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.maximum_timeout).to be_nil @@ -179,8 +197,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:value) { "#{param}_value" } it "updates provided Runner's parameter" do - post api('/runners'), token: registration_token, - info: { param => value } + post api('/runners'), params: { + token: registration_token, + info: { param => value } + } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.read_attribute(param.to_sym)).to eq(value) @@ -190,8 +210,8 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it "sets the runner's ip_address" do post api('/runners'), - { token: registration_token }, - { 'REMOTE_ADDR' => '123.111.123.111' } + params: { token: registration_token }, + headers: { 'REMOTE_ADDR' => '123.111.123.111' } expect(response).to have_gitlab_http_status 201 expect(Ci::Runner.first.ip_address).to eq('123.111.123.111') @@ -209,7 +229,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when invalid token is provided' do it 'returns 403 error' do - delete api('/runners'), token: 'invalid' + delete api('/runners'), params: { token: 'invalid' } expect(response).to have_gitlab_http_status 403 end @@ -219,7 +239,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:runner) { create(:ci_runner) } it 'deletes Runner' do - delete api('/runners'), token: runner.token + delete api('/runners'), params: { token: runner.token } expect(response).to have_gitlab_http_status 204 expect(Ci::Runner.count).to eq(0) @@ -245,7 +265,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when invalid token is provided' do it 'returns 403 error' do - post api('/runners/verify'), token: 'invalid-token' + post api('/runners/verify'), params: { token: 'invalid-token' } expect(response).to have_gitlab_http_status 403 end @@ -253,7 +273,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when valid token is provided' do it 'verifies Runner credentials' do - post api('/runners/verify'), token: runner.token + post api('/runners/verify'), params: { token: runner.token } expect(response).to have_gitlab_http_status 200 end @@ -342,7 +362,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when invalid token is provided' do it 'returns 403 error' do - post api('/jobs/request'), token: 'invalid' + post api('/jobs/request'), params: { token: 'invalid' } expect(response).to have_gitlab_http_status 403 end @@ -499,8 +519,8 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it "sets the runner's ip_address" do post api('/jobs/request'), - { token: runner.token }, - { 'User-Agent' => user_agent, 'REMOTE_ADDR' => '123.222.123.222' } + params: { token: runner.token }, + headers: { 'User-Agent' => user_agent, 'REMOTE_ADDR' => '123.222.123.222' } expect(response).to have_gitlab_http_status 201 expect(runner.reload.ip_address).to eq('123.222.123.222') @@ -752,7 +772,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do def request_job(token = runner.token, **params) new_params = params.merge(token: token, last_update: last_update) - post api('/jobs/request'), new_params, { 'User-Agent' => user_agent } + post api('/jobs/request'), params: new_params, headers: { 'User-Agent' => user_agent } end end end @@ -893,7 +913,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do def update_job(token = job.token, **params) new_params = params.merge(token: token) - put api("/jobs/#{job.id}"), new_params + put api("/jobs/#{job.id}"), params: new_params end def update_job_after_time(update_interval = 20.minutes, state = 'running') @@ -1113,7 +1133,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do end Timecop.travel(job.updated_at + update_interval) do - patch api("/jobs/#{job.id}/trace"), content, request_headers + patch api("/jobs/#{job.id}/trace"), params: content, headers: request_headers job.reload end end @@ -1244,7 +1264,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do end def authorize_artifacts(params = {}, request_headers = headers) - post api("/jobs/#{job.id}/artifacts/authorize"), params, request_headers + post api("/jobs/#{job.id}/artifacts/authorize"), params: params, headers: request_headers end def authorize_artifacts_with_token_in_params(params = {}, request_headers = headers) @@ -1347,7 +1367,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when artifacts post request does not contain file' do it 'fails to post artifacts without file' do - post api("/jobs/#{job.id}/artifacts"), {}, headers_with_token + post api("/jobs/#{job.id}/artifacts"), params: {}, headers: headers_with_token expect(response).to have_gitlab_http_status(400) end @@ -1355,7 +1375,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'GitLab Workhorse is not configured' do it 'fails to post artifacts without GitLab-Workhorse' do - post api("/jobs/#{job.id}/artifacts"), { token: job.token }, {} + post api("/jobs/#{job.id}/artifacts"), params: { token: job.token }, headers: {} expect(response).to have_gitlab_http_status(403) end @@ -1372,7 +1392,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do before do stub_application_setting(default_artifacts_expire_in: default_artifacts_expire_in) - post(api("/jobs/#{job.id}/artifacts"), post_data, headers_with_token) + post(api("/jobs/#{job.id}/artifacts"), params: post_data, headers: headers_with_token) end context 'when an expire_in is given' do @@ -1427,7 +1447,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:stored_metadata_sha256) { job.reload.job_artifacts_metadata.file_sha256 } before do - post(api("/jobs/#{job.id}/artifacts"), post_data, headers_with_token) + post(api("/jobs/#{job.id}/artifacts"), params: post_data, headers: headers_with_token) end context 'when posts data accelerated by workhorse is correct' do @@ -1545,7 +1565,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do 'file.name' => file.original_filename }) - post api("/jobs/#{job.id}/artifacts"), params, headers + post api("/jobs/#{job.id}/artifacts"), params: params, headers: headers end end @@ -1631,7 +1651,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do params = params.merge(token: token) job.reload - get api("/jobs/#{job.id}/artifacts"), params, request_headers + get api("/jobs/#{job.id}/artifacts"), params: params, headers: request_headers end end end diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index 49a79d2ccf9..7f11c8c9fe8 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -400,14 +400,14 @@ describe API::Runners do end def update_runner(id, user, args) - put api("/runners/#{id}", user), args + put api("/runners/#{id}", user), params: args end end context 'authorized user' do context 'when runner is shared' do it 'does not update runner' do - put api("/runners/#{shared_runner.id}", user), description: 'test' + put api("/runners/#{shared_runner.id}", user), params: { description: 'test' } expect(response).to have_gitlab_http_status(403) end @@ -415,14 +415,14 @@ describe API::Runners do context 'when runner is not shared' do it 'does not update project runner without access to it' do - put api("/runners/#{project_runner.id}", user2), description: 'test' + put api("/runners/#{project_runner.id}", user2), params: { description: 'test' } expect(response).to have_http_status(403) end it 'updates project runner with access to it' do description = project_runner.description - put api("/runners/#{project_runner.id}", admin), description: 'test' + put api("/runners/#{project_runner.id}", admin), params: { description: 'test' } project_runner.reload expect(response).to have_gitlab_http_status(200) @@ -741,14 +741,14 @@ describe API::Runners do it 'enables specific runner' do expect do - post api("/projects/#{project.id}/runners", user), runner_id: project_runner2.id + post api("/projects/#{project.id}/runners", user), params: { runner_id: project_runner2.id } end.to change { project.runners.count }.by(+1) expect(response).to have_gitlab_http_status(201) end it 'avoids changes when enabling already enabled runner' do expect do - post api("/projects/#{project.id}/runners", user), runner_id: project_runner.id + post api("/projects/#{project.id}/runners", user), params: { runner_id: project_runner.id } end.to change { project.runners.count }.by(0) expect(response).to have_gitlab_http_status(400) end @@ -757,20 +757,20 @@ describe API::Runners do project_runner2.update(locked: true) expect do - post api("/projects/#{project.id}/runners", user), runner_id: project_runner2.id + post api("/projects/#{project.id}/runners", user), params: { runner_id: project_runner2.id } end.to change { project.runners.count }.by(0) expect(response).to have_gitlab_http_status(403) end it 'does not enable shared runner' do - post api("/projects/#{project.id}/runners", user), runner_id: shared_runner.id + post api("/projects/#{project.id}/runners", user), params: { runner_id: shared_runner.id } expect(response).to have_gitlab_http_status(403) end it 'does not enable group runner' do - post api("/projects/#{project.id}/runners", user), runner_id: group_runner.id + post api("/projects/#{project.id}/runners", user), params: { runner_id: group_runner.id } expect(response).to have_http_status(403) end @@ -781,7 +781,7 @@ describe API::Runners do it 'enables any specific runner' do expect do - post api("/projects/#{project.id}/runners", admin), runner_id: new_project_runner.id + post api("/projects/#{project.id}/runners", admin), params: { runner_id: new_project_runner.id } end.to change { project.runners.count }.by(+1) expect(response).to have_gitlab_http_status(201) end @@ -789,7 +789,7 @@ describe API::Runners do it 'enables a instance type runner' do expect do - post api("/projects/#{project.id}/runners", admin), runner_id: shared_runner.id + post api("/projects/#{project.id}/runners", admin), params: { runner_id: shared_runner.id } end.to change { project.runners.count }.by(1) expect(shared_runner.reload).not_to be_instance_type @@ -808,7 +808,7 @@ describe API::Runners do let!(:new_project_runner) { create(:ci_runner, :project) } it 'does not enable runner without access to' do - post api("/projects/#{project.id}/runners", user), runner_id: new_project_runner.id + post api("/projects/#{project.id}/runners", user), params: { runner_id: new_project_runner.id } expect(response).to have_gitlab_http_status(403) end diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb index f8e468be170..831f47debeb 100644 --- a/spec/requests/api/search_spec.rb +++ b/spec/requests/api/search_spec.rb @@ -16,7 +16,7 @@ describe API::Search do describe 'GET /search' do context 'when user is not authenticated' do it 'returns 401 error' do - get api('/search'), scope: 'projects', search: 'awesome' + get api('/search'), params: { scope: 'projects', search: 'awesome' } expect(response).to have_gitlab_http_status(401) end @@ -24,7 +24,7 @@ describe API::Search do context 'when scope is not supported' do it 'returns 400 error' do - get api('/search', user), scope: 'unsupported', search: 'awesome' + get api('/search', user), params: { scope: 'unsupported', search: 'awesome' } expect(response).to have_gitlab_http_status(400) end @@ -32,7 +32,7 @@ describe API::Search do context 'when scope is missing' do it 'returns 400 error' do - get api('/search', user), search: 'awesome' + get api('/search', user), params: { search: 'awesome' } expect(response).to have_gitlab_http_status(400) end @@ -41,7 +41,7 @@ describe API::Search do context 'with correct params' do context 'for projects scope' do before do - get api('/search', user), scope: 'projects', search: 'awesome' + get api('/search', user), params: { scope: 'projects', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/projects' @@ -51,7 +51,7 @@ describe API::Search do before do create(:issue, project: project, title: 'awesome issue') - get api('/search', user), scope: 'issues', search: 'awesome' + get api('/search', user), params: { scope: 'issues', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/issues' @@ -61,7 +61,7 @@ describe API::Search do before do create(:merge_request, source_project: repo_project, title: 'awesome mr') - get api('/search', user), scope: 'merge_requests', search: 'awesome' + get api('/search', user), params: { scope: 'merge_requests', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/merge_requests' @@ -71,7 +71,7 @@ describe API::Search do before do create(:milestone, project: project, title: 'awesome milestone') - get api('/search', user), scope: 'milestones', search: 'awesome' + get api('/search', user), params: { scope: 'milestones', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/milestones' @@ -81,7 +81,7 @@ describe API::Search do before do create(:snippet, :public, title: 'awesome snippet', content: 'snippet content') - get api('/search', user), scope: 'snippet_titles', search: 'awesome' + get api('/search', user), params: { scope: 'snippet_titles', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/snippets' @@ -91,7 +91,7 @@ describe API::Search do before do create(:snippet, :public, title: 'awesome snippet', content: 'snippet content') - get api('/search', user), scope: 'snippet_blobs', search: 'content' + get api('/search', user), params: { scope: 'snippet_blobs', search: 'content' } end it_behaves_like 'response is correct', schema: 'public_api/v4/snippets' @@ -102,7 +102,7 @@ describe API::Search do describe "GET /groups/:id/search" do context 'when user is not authenticated' do it 'returns 401 error' do - get api("/groups/#{group.id}/search"), scope: 'projects', search: 'awesome' + get api("/groups/#{group.id}/search"), params: { scope: 'projects', search: 'awesome' } expect(response).to have_gitlab_http_status(401) end @@ -110,7 +110,7 @@ describe API::Search do context 'when scope is not supported' do it 'returns 400 error' do - get api("/groups/#{group.id}/search", user), scope: 'unsupported', search: 'awesome' + get api("/groups/#{group.id}/search", user), params: { scope: 'unsupported', search: 'awesome' } expect(response).to have_gitlab_http_status(400) end @@ -118,7 +118,7 @@ describe API::Search do context 'when scope is missing' do it 'returns 400 error' do - get api("/groups/#{group.id}/search", user), search: 'awesome' + get api("/groups/#{group.id}/search", user), params: { search: 'awesome' } expect(response).to have_gitlab_http_status(400) end @@ -126,7 +126,7 @@ describe API::Search do context 'when group does not exist' do it 'returns 404 error' do - get api('/groups/9999/search', user), scope: 'issues', search: 'awesome' + get api('/groups/9999/search', user), params: { scope: 'issues', search: 'awesome' } expect(response).to have_gitlab_http_status(404) end @@ -136,7 +136,7 @@ describe API::Search do it 'returns 404 error' do private_group = create(:group, :private) - get api("/groups/#{private_group.id}/search", user), scope: 'issues', search: 'awesome' + get api("/groups/#{private_group.id}/search", user), params: { scope: 'issues', search: 'awesome' } expect(response).to have_gitlab_http_status(404) end @@ -145,7 +145,7 @@ describe API::Search do context 'with correct params' do context 'for projects scope' do before do - get api("/groups/#{group.id}/search", user), scope: 'projects', search: 'awesome' + get api("/groups/#{group.id}/search", user), params: { scope: 'projects', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/projects' @@ -155,7 +155,7 @@ describe API::Search do before do create(:issue, project: project, title: 'awesome issue') - get api("/groups/#{group.id}/search", user), scope: 'issues', search: 'awesome' + get api("/groups/#{group.id}/search", user), params: { scope: 'issues', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/issues' @@ -165,7 +165,7 @@ describe API::Search do before do create(:merge_request, source_project: repo_project, title: 'awesome mr') - get api("/groups/#{group.id}/search", user), scope: 'merge_requests', search: 'awesome' + get api("/groups/#{group.id}/search", user), params: { scope: 'merge_requests', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/merge_requests' @@ -175,7 +175,7 @@ describe API::Search do before do create(:milestone, project: project, title: 'awesome milestone') - get api("/groups/#{group.id}/search", user), scope: 'milestones', search: 'awesome' + get api("/groups/#{group.id}/search", user), params: { scope: 'milestones', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/milestones' @@ -187,7 +187,7 @@ describe API::Search do create(:milestone, project: project, title: 'awesome milestone') create(:milestone, project: another_project, title: 'awesome milestone other project') - get api("/groups/#{CGI.escape(group.full_path)}/search", user), scope: 'milestones', search: 'awesome' + get api("/groups/#{CGI.escape(group.full_path)}/search", user), params: { scope: 'milestones', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/milestones' @@ -198,7 +198,7 @@ describe API::Search do describe "GET /projects/:id/search" do context 'when user is not authenticated' do it 'returns 401 error' do - get api("/projects/#{project.id}/search"), scope: 'issues', search: 'awesome' + get api("/projects/#{project.id}/search"), params: { scope: 'issues', search: 'awesome' } expect(response).to have_gitlab_http_status(401) end @@ -206,7 +206,7 @@ describe API::Search do context 'when scope is not supported' do it 'returns 400 error' do - get api("/projects/#{project.id}/search", user), scope: 'unsupported', search: 'awesome' + get api("/projects/#{project.id}/search", user), params: { scope: 'unsupported', search: 'awesome' } expect(response).to have_gitlab_http_status(400) end @@ -214,7 +214,7 @@ describe API::Search do context 'when scope is missing' do it 'returns 400 error' do - get api("/projects/#{project.id}/search", user), search: 'awesome' + get api("/projects/#{project.id}/search", user), params: { search: 'awesome' } expect(response).to have_gitlab_http_status(400) end @@ -222,7 +222,7 @@ describe API::Search do context 'when project does not exist' do it 'returns 404 error' do - get api('/projects/9999/search', user), scope: 'issues', search: 'awesome' + get api('/projects/9999/search', user), params: { scope: 'issues', search: 'awesome' } expect(response).to have_gitlab_http_status(404) end @@ -232,7 +232,7 @@ describe API::Search do it 'returns 404 error' do project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) - get api("/projects/#{project.id}/search", user), scope: 'issues', search: 'awesome' + get api("/projects/#{project.id}/search", user), params: { scope: 'issues', search: 'awesome' } expect(response).to have_gitlab_http_status(404) end @@ -243,7 +243,7 @@ describe API::Search do before do create(:issue, project: project, title: 'awesome issue') - get api("/projects/#{project.id}/search", user), scope: 'issues', search: 'awesome' + get api("/projects/#{project.id}/search", user), params: { scope: 'issues', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/issues' @@ -253,7 +253,7 @@ describe API::Search do before do create(:merge_request, source_project: repo_project, title: 'awesome mr') - get api("/projects/#{repo_project.id}/search", user), scope: 'merge_requests', search: 'awesome' + get api("/projects/#{repo_project.id}/search", user), params: { scope: 'merge_requests', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/merge_requests' @@ -263,7 +263,7 @@ describe API::Search do before do create(:milestone, project: project, title: 'awesome milestone') - get api("/projects/#{project.id}/search", user), scope: 'milestones', search: 'awesome' + get api("/projects/#{project.id}/search", user), params: { scope: 'milestones', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/milestones' @@ -273,7 +273,7 @@ describe API::Search do before do create(:note_on_merge_request, project: project, note: 'awesome note') - get api("/projects/#{project.id}/search", user), scope: 'notes', search: 'awesome' + get api("/projects/#{project.id}/search", user), params: { scope: 'notes', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/notes' @@ -284,7 +284,7 @@ describe API::Search do wiki = create(:project_wiki, project: project) create(:wiki_page, wiki: wiki, attrs: { title: 'home', content: "Awesome page" }) - get api("/projects/#{project.id}/search", user), scope: 'wiki_blobs', search: 'awesome' + get api("/projects/#{project.id}/search", user), params: { scope: 'wiki_blobs', search: 'awesome' } end it_behaves_like 'response is correct', schema: 'public_api/v4/blobs' @@ -292,7 +292,7 @@ describe API::Search do context 'for commits scope' do before do - get api("/projects/#{repo_project.id}/search", user), scope: 'commits', search: '498214de67004b1da3d820901307bed2a68a8ef6' + get api("/projects/#{repo_project.id}/search", user), params: { scope: 'commits', search: '498214de67004b1da3d820901307bed2a68a8ef6' } end it_behaves_like 'response is correct', schema: 'public_api/v4/commits_details' @@ -300,7 +300,7 @@ describe API::Search do context 'for commits scope with project path as id' do before do - get api("/projects/#{CGI.escape(repo_project.full_path)}/search", user), scope: 'commits', search: '498214de67004b1da3d820901307bed2a68a8ef6' + get api("/projects/#{CGI.escape(repo_project.full_path)}/search", user), params: { scope: 'commits', search: '498214de67004b1da3d820901307bed2a68a8ef6' } end it_behaves_like 'response is correct', schema: 'public_api/v4/commits_details' @@ -308,14 +308,14 @@ describe API::Search do context 'for blobs scope' do before do - get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'monitors' + get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'monitors' } end it_behaves_like 'response is correct', schema: 'public_api/v4/blobs', size: 2 context 'filters' do it 'by filename' do - get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'mon filename:PROCESS.md' + get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'mon filename:PROCESS.md' } expect(response).to have_gitlab_http_status(200) expect(json_response.size).to eq(2) @@ -323,14 +323,14 @@ describe API::Search do end it 'by path' do - get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'mon path:markdown' + get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'mon path:markdown' } expect(response).to have_gitlab_http_status(200) expect(json_response.size).to eq(8) end it 'by extension' do - get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'mon extension:md' + get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'mon extension:md' } expect(response).to have_gitlab_http_status(200) expect(json_response.size).to eq(11) diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb index 236f8d7faf5..e260aa21e25 100644 --- a/spec/requests/api/services_spec.rb +++ b/spec/requests/api/services_spec.rb @@ -14,7 +14,7 @@ describe API::Services do include_context service it "updates #{service} settings" do - put api("/projects/#{project.id}/services/#{dashed_service}", user), service_attrs + put api("/projects/#{project.id}/services/#{dashed_service}", user), params: service_attrs expect(response).to have_gitlab_http_status(200) @@ -22,7 +22,7 @@ describe API::Services do event = current_service.event_names.empty? ? "foo" : current_service.event_names.first state = current_service[event] || false - put api("/projects/#{project.id}/services/#{dashed_service}?#{event}=#{!state}", user), service_attrs + put api("/projects/#{project.id}/services/#{dashed_service}?#{event}=#{!state}", user), params: service_attrs expect(response).to have_gitlab_http_status(200) expect(project.services.first[event]).not_to eq(state) unless event == "foo" @@ -44,7 +44,7 @@ describe API::Services do expected_code = 400 end - put api("/projects/#{project.id}/services/#{dashed_service}", user), attrs + put api("/projects/#{project.id}/services/#{dashed_service}", user), params: attrs expect(response.status).to eq(expected_code) end @@ -127,7 +127,7 @@ describe API::Services do end it 'when the service is inactive' do - post api("/projects/#{project.id}/services/#{service_name}/trigger"), params + post api("/projects/#{project.id}/services/#{service_name}/trigger"), params: params expect(response).to have_gitlab_http_status(404) end @@ -142,7 +142,7 @@ describe API::Services do end it 'returns status 200' do - post api("/projects/#{project.id}/services/#{service_name}/trigger"), params + post api("/projects/#{project.id}/services/#{service_name}/trigger"), params: params expect(response).to have_gitlab_http_status(200) end @@ -150,7 +150,7 @@ describe API::Services do context 'when the project can not be found' do it 'returns a generic 404' do - post api("/projects/404/services/#{service_name}/trigger"), params + post api("/projects/404/services/#{service_name}/trigger"), params: params expect(response).to have_gitlab_http_status(404) expect(json_response["message"]).to eq("404 Service Not Found") @@ -170,7 +170,7 @@ describe API::Services do end it 'returns status 200' do - post api("/projects/#{project.id}/services/#{service_name}/trigger"), token: 'token', text: 'help' + post api("/projects/#{project.id}/services/#{service_name}/trigger"), params: { token: 'token', text: 'help' } expect(response).to have_gitlab_http_status(200) expect(json_response['response_type']).to eq("ephemeral") @@ -192,7 +192,7 @@ describe API::Services do end it 'accepts a username for update' do - put api("/projects/#{project.id}/services/mattermost", user), params.merge(username: 'new_username') + put api("/projects/#{project.id}/services/mattermost", user), params: params.merge(username: 'new_username') expect(response).to have_gitlab_http_status(200) expect(json_response['properties']['username']).to eq('new_username') diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb index 84c7210f6bb..cfbda63bb30 100644 --- a/spec/requests/api/settings_spec.rb +++ b/spec/requests/api/settings_spec.rb @@ -42,27 +42,29 @@ describe API::Settings, 'Settings' do it "updates application settings" do put api("/application/settings", admin), - default_projects_limit: 3, - password_authentication_enabled_for_web: false, - repository_storages: ['custom'], - plantuml_enabled: true, - plantuml_url: 'http://plantuml.example.com', - default_snippet_visibility: 'internal', - restricted_visibility_levels: ['public'], - default_artifacts_expire_in: '2 days', - help_page_text: 'custom help text', - help_page_hide_commercial_content: true, - help_page_support_url: 'http://example.com/help', - project_export_enabled: false, - rsa_key_restriction: ApplicationSetting::FORBIDDEN_KEY_VALUE, - dsa_key_restriction: 2048, - ecdsa_key_restriction: 384, - ed25519_key_restriction: 256, - enforce_terms: true, - terms: 'Hello world!', - performance_bar_allowed_group_path: group.full_path, - instance_statistics_visibility_private: true, - diff_max_patch_bytes: 150_000 + params: { + default_projects_limit: 3, + password_authentication_enabled_for_web: false, + repository_storages: ['custom'], + plantuml_enabled: true, + plantuml_url: 'http://plantuml.example.com', + default_snippet_visibility: 'internal', + restricted_visibility_levels: ['public'], + default_artifacts_expire_in: '2 days', + help_page_text: 'custom help text', + help_page_hide_commercial_content: true, + help_page_support_url: 'http://example.com/help', + project_export_enabled: false, + rsa_key_restriction: ApplicationSetting::FORBIDDEN_KEY_VALUE, + dsa_key_restriction: 2048, + ecdsa_key_restriction: 384, + ed25519_key_restriction: 256, + enforce_terms: true, + terms: 'Hello world!', + performance_bar_allowed_group_path: group.full_path, + instance_statistics_visibility_private: true, + diff_max_patch_bytes: 150_000 + } expect(response).to have_gitlab_http_status(200) expect(json_response['default_projects_limit']).to eq(3) @@ -91,7 +93,7 @@ describe API::Settings, 'Settings' do it "supports legacy performance_bar_allowed_group_id" do put api("/application/settings", admin), - performance_bar_allowed_group_id: group.full_path + params: { performance_bar_allowed_group_id: group.full_path } expect(response).to have_gitlab_http_status(200) expect(json_response['performance_bar_allowed_group_id']).to eq(group.id) @@ -99,8 +101,10 @@ describe API::Settings, 'Settings' do it "supports legacy performance_bar_enabled" do put api("/application/settings", admin), - performance_bar_enabled: false, - performance_bar_allowed_group_id: group.full_path + params: { + performance_bar_enabled: false, + performance_bar_allowed_group_id: group.full_path + } expect(response).to have_gitlab_http_status(200) expect(json_response['performance_bar_allowed_group_id']).to be_nil @@ -108,7 +112,7 @@ describe API::Settings, 'Settings' do context "missing plantuml_url value when plantuml_enabled is true" do it "returns a blank parameter error message" do - put api("/application/settings", admin), plantuml_enabled: true + put api("/application/settings", admin), params: { plantuml_enabled: true } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('plantuml_url is missing') diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb index c546ba3e127..7c8512f7589 100644 --- a/spec/requests/api/snippets_spec.rb +++ b/spec/requests/api/snippets_spec.rb @@ -143,7 +143,7 @@ describe API::Snippets do it 'creates a new snippet' do expect do - post api("/snippets/", user), params + post api("/snippets/", user), params: params end.to change { PersonalSnippet.count }.by(1) expect(response).to have_gitlab_http_status(201) @@ -156,14 +156,14 @@ describe API::Snippets do it 'returns 400 for missing parameters' do params.delete(:title) - post api("/snippets/", user), params + post api("/snippets/", user), params: params expect(response).to have_gitlab_http_status(400) end context 'when the snippet is spam' do def create_snippet(snippet_params = {}) - post api('/snippets', user), params.merge(snippet_params) + post api('/snippets', user), params: params.merge(snippet_params) end before do @@ -205,7 +205,7 @@ describe API::Snippets do new_content = 'New content' new_description = 'New description' - put api("/snippets/#{snippet.id}", user), content: new_content, description: new_description + put api("/snippets/#{snippet.id}", user), params: { content: new_content, description: new_description } expect(response).to have_gitlab_http_status(200) snippet.reload @@ -214,14 +214,14 @@ describe API::Snippets do end it 'returns 404 for invalid snippet id' do - put api("/snippets/1234", user), title: 'foo' + put api("/snippets/1234", user), params: { title: 'foo' } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Snippet Not Found') end it "returns 404 for another user's snippet" do - put api("/snippets/#{snippet.id}", other_user), title: 'fubar' + put api("/snippets/#{snippet.id}", other_user), params: { title: 'fubar' } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 Snippet Not Found') @@ -235,7 +235,7 @@ describe API::Snippets do context 'when the snippet is spam' do def update_snippet(snippet_params = {}) - put api("/snippets/#{snippet.id}", user), snippet_params + put api("/snippets/#{snippet.id}", user), params: snippet_params end before do diff --git a/spec/requests/api/submodules_spec.rb b/spec/requests/api/submodules_spec.rb index fa447c028c2..c482a85c68f 100644 --- a/spec/requests/api/submodules_spec.rb +++ b/spec/requests/api/submodules_spec.rb @@ -31,7 +31,7 @@ describe API::Submodules do describe "PUT /projects/:id/repository/submodule/:submodule" do context 'when unauthenticated' do it 'returns 401' do - put api(route(submodule)), params + put api(route(submodule)), params: params expect(response).to have_gitlab_http_status(401) end @@ -39,7 +39,7 @@ describe API::Submodules do context 'when authenticated', 'as a guest' do it 'returns 403' do - put api(route(submodule), guest), params + put api(route(submodule), guest), params: params expect(response).to have_gitlab_http_status(403) end @@ -53,13 +53,13 @@ describe API::Submodules do end it 'returns 400 if branch is missing' do - put api(route(submodule), user), params.except(:branch) + put api(route(submodule), user), params: params.except(:branch) expect(response).to have_gitlab_http_status(400) end it 'returns 400 if commit_sha is missing' do - put api(route(submodule), user), params.except(:commit_sha) + put api(route(submodule), user), params: params.except(:commit_sha) expect(response).to have_gitlab_http_status(400) end @@ -67,7 +67,7 @@ describe API::Submodules do it 'returns the commmit' do head_commit = project.repository.commit.id - put api(route(submodule), user), params + put api(route(submodule), user), params: params expect(response).to have_gitlab_http_status(200) expect(json_response['message']).to eq commit_message @@ -87,7 +87,7 @@ describe API::Submodules do .with(any_args, hash_including(submodule: submodule)) .and_call_original - put api(route(encoded_submodule), user), params + put api(route(encoded_submodule), user), params: params expect(response).to have_gitlab_http_status(200) expect(json_response['id']).to eq project.repository.commit(branch).id diff --git a/spec/requests/api/suggestions_spec.rb b/spec/requests/api/suggestions_spec.rb new file mode 100644 index 00000000000..3c2842e5725 --- /dev/null +++ b/spec/requests/api/suggestions_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe API::Suggestions do + let(:project) { create(:project, :repository) } + let(:user) { create(:user) } + + let(:merge_request) do + create(:merge_request, source_project: project, + target_project: project) + end + + let(:position) do + Gitlab::Diff::Position.new(old_path: "files/ruby/popen.rb", + new_path: "files/ruby/popen.rb", + old_line: nil, + new_line: 9, + diff_refs: merge_request.diff_refs) + end + + let(:diff_note) do + create(:diff_note_on_merge_request, noteable: merge_request, + position: position, + project: project) + end + + describe "PUT /suggestions/:id/apply" do + let(:url) { "/suggestions/#{suggestion.id}/apply" } + + context 'when successfully applies patch' do + let(:suggestion) do + create(:suggestion, note: diff_note, + from_content: " raise RuntimeError, \"System commands must be given as an array of strings\"\n", + to_content: " raise RuntimeError, 'Explosion'\n # explosion?") + end + + it 'returns 200 with json content' do + project.add_maintainer(user) + + put api(url, user), params: { id: suggestion.id } + + expect(response).to have_gitlab_http_status(200) + expect(json_response) + .to include('id', 'from_original_line', 'to_original_line', + 'from_line', 'to_line', 'appliable', 'applied', + 'from_content', 'to_content') + end + end + + context 'when not able to apply patch' do + let(:suggestion) do + create(:suggestion, :unappliable, note: diff_note) + end + + it 'returns 400 with json content' do + project.add_maintainer(user) + + put api(url, user), params: { id: suggestion.id } + + expect(response).to have_gitlab_http_status(400) + expect(json_response).to eq({ 'message' => 'Suggestion is not appliable' }) + end + end + + context 'when unauthorized' do + let(:suggestion) do + create(:suggestion, note: diff_note, + from_content: " raise RuntimeError, \"System commands must be given as an array of strings\"\n", + to_content: " raise RuntimeError, 'Explosion'\n # explosion?") + end + + it 'returns 403 with json content' do + project.add_reporter(user) + + put api(url, user), params: { id: suggestion.id } + + expect(response).to have_gitlab_http_status(403) + expect(json_response).to eq({ 'message' => '403 Forbidden' }) + end + end + end +end diff --git a/spec/requests/api/system_hooks_spec.rb b/spec/requests/api/system_hooks_spec.rb index 6c57d443cbf..b6e8d74c2e9 100644 --- a/spec/requests/api/system_hooks_spec.rb +++ b/spec/requests/api/system_hooks_spec.rb @@ -45,7 +45,7 @@ describe API::SystemHooks do describe "POST /hooks" do it "creates new hook" do expect do - post api("/hooks", admin), url: 'http://example.com' + post api("/hooks", admin), params: { url: 'http://example.com' } end.to change { SystemHook.count }.by(1) end @@ -56,7 +56,7 @@ describe API::SystemHooks do end it "responds with 400 if url is invalid" do - post api("/hooks", admin), url: 'hp://mep.mep' + post api("/hooks", admin), params: { url: 'hp://mep.mep' } expect(response).to have_gitlab_http_status(400) end @@ -68,7 +68,7 @@ describe API::SystemHooks do end it 'sets default values for events' do - post api('/hooks', admin), url: 'http://mep.mep' + post api('/hooks', admin), params: { url: 'http://mep.mep' } expect(response).to have_gitlab_http_status(201) expect(json_response['enable_ssl_verification']).to be true @@ -79,11 +79,13 @@ describe API::SystemHooks do it 'sets explicit values for events' do post api('/hooks', admin), - url: 'http://mep.mep', - enable_ssl_verification: false, - push_events: true, - tag_push_events: true, - merge_requests_events: true + params: { + url: 'http://mep.mep', + enable_ssl_verification: false, + push_events: true, + tag_push_events: true, + merge_requests_events: true + } expect(response).to have_http_status(201) expect(json_response['enable_ssl_verification']).to be false diff --git a/spec/requests/api/tags_spec.rb b/spec/requests/api/tags_spec.rb index 98f995df06f..d09b6fe72b1 100644 --- a/spec/requests/api/tags_spec.rb +++ b/spec/requests/api/tags_spec.rb @@ -107,9 +107,12 @@ describe API::Tags do context 'with releases' do let(:description) { 'Awesome release!' } - before do - release = project.releases.find_or_initialize_by(tag: tag_name) - release.update(description: description) + let!(:release) do + create(:release, + :legacy, + project: project, + tag: tag_name, + description: description) end it 'returns an array of project tags with release info' do @@ -193,7 +196,7 @@ describe API::Tags do shared_examples_for 'repository new tag' do it 'creates a new tag' do - post api(route, current_user), tag_name: tag_name, ref: 'master' + post api(route, current_user), params: { tag_name: tag_name, ref: 'master' } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/tag') @@ -248,26 +251,26 @@ describe API::Tags do end it 'returns 400 if tag name is invalid' do - post api(route, current_user), tag_name: 'new design', ref: 'master' + post api(route, current_user), params: { tag_name: 'new design', ref: 'master' } expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('Tag name invalid') end it 'returns 400 if tag already exists' do - post api(route, current_user), tag_name: 'new_design1', ref: 'master' + post api(route, current_user), params: { tag_name: 'new_design1', ref: 'master' } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/tag') - post api(route, current_user), tag_name: 'new_design1', ref: 'master' + post api(route, current_user), params: { tag_name: 'new_design1', ref: 'master' } expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('Tag new_design1 already exists') end it 'returns 400 if ref name is invalid' do - post api(route, current_user), tag_name: 'new_design3', ref: 'foo' + post api(route, current_user), params: { tag_name: 'new_design3', ref: 'foo' } expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('Target foo is invalid') @@ -275,7 +278,7 @@ describe API::Tags do context 'lightweight tags with release notes' do it 'creates a new tag' do - post api(route, current_user), tag_name: tag_name, ref: 'master', release_description: 'Wow' + post api(route, current_user), params: { tag_name: tag_name, ref: 'master', release_description: 'Wow' } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/tag') @@ -294,7 +297,7 @@ describe API::Tags do system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.name #{user.name})) system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.email #{user.email})) - post api(route, current_user), tag_name: 'v7.1.0', ref: 'master', message: 'Release 7.1.0' + post api(route, current_user), params: { tag_name: 'v7.1.0', ref: 'master', message: 'Release 7.1.0' } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/tag') @@ -360,7 +363,7 @@ describe API::Tags do shared_examples_for 'repository new release' do it 'creates description for existing git tag' do - post api(route, user), description: description + post api(route, user), params: { description: description } expect(response).to have_gitlab_http_status(201) expect(response).to match_response_schema('public_api/v4/release') @@ -372,8 +375,8 @@ describe API::Tags do let(:tag_name) { 'unknown' } it_behaves_like '404 response' do - let(:request) { post api(route, current_user), description: description } - let(:message) { 'Tag does not exist' } + let(:request) { post api(route, current_user), params: { description: description } } + let(:message) { '404 Tag Not Found' } end end @@ -381,7 +384,7 @@ describe API::Tags do include_context 'disabled repository' it_behaves_like '403 response' do - let(:request) { post api(route, current_user), description: description } + let(:request) { post api(route, current_user), params: { description: description } } end end end @@ -398,13 +401,10 @@ describe API::Tags do end context 'on tag with existing release' do - before do - release = project.releases.find_or_initialize_by(tag: tag_name) - release.update(description: description) - end + let!(:release) { create(:release, :legacy, project: project, tag: tag_name, description: description) } it 'returns 409 if there is already a release' do - post api(route, user), description: description + post api(route, user), params: { description: description } expect(response).to have_gitlab_http_status(409) expect(json_response['message']).to eq('Release already exists') @@ -420,13 +420,16 @@ describe API::Tags do shared_examples_for 'repository update release' do context 'on tag with existing release' do - before do - release = project.releases.find_or_initialize_by(tag: tag_name) - release.update(description: description) + let!(:release) do + create(:release, + :legacy, + project: project, + tag: tag_name, + description: description) end it 'updates the release description' do - put api(route, current_user), description: new_description + put api(route, current_user), params: { description: new_description } expect(response).to have_gitlab_http_status(200) expect(json_response['tag_name']).to eq(tag_name) @@ -437,9 +440,9 @@ describe API::Tags do context 'when tag does not exist' do let(:tag_name) { 'unknown' } - it_behaves_like '404 response' do - let(:request) { put api(route, current_user), description: new_description } - let(:message) { 'Tag does not exist' } + it_behaves_like '403 response' do + let(:request) { put api(route, current_user), params: { description: new_description } } + let(:message) { '403 Forbidden' } end end @@ -447,7 +450,7 @@ describe API::Tags do include_context 'disabled repository' it_behaves_like '403 response' do - let(:request) { put api(route, current_user), description: new_description } + let(:request) { put api(route, current_user), params: { description: new_description } } end end end @@ -464,9 +467,9 @@ describe API::Tags do end context 'when release does not exist' do - it_behaves_like '404 response' do - let(:request) { put api(route, current_user), description: new_description } - let(:message) { 'Release does not exist' } + it_behaves_like '403 response' do + let(:request) { put api(route, current_user), params: { description: new_description } } + let(:message) { '403 Forbidden' } end end end diff --git a/spec/requests/api/todos_spec.rb b/spec/requests/api/todos_spec.rb index b5cf04e7f22..f121a1d3b78 100644 --- a/spec/requests/api/todos_spec.rb +++ b/spec/requests/api/todos_spec.rb @@ -49,7 +49,7 @@ describe API::Todos do context 'and using the author filter' do it 'filters based on author_id param' do - get api('/todos', john_doe), { author_id: author_2.id } + get api('/todos', john_doe), params: { author_id: author_2.id } expect(response.status).to eq(200) expect(response).to include_pagination_headers @@ -62,7 +62,7 @@ describe API::Todos do it 'filters based on type param' do create(:todo, project: project_1, author: author_2, user: john_doe, target: merge_request) - get api('/todos', john_doe), { type: 'MergeRequest' } + get api('/todos', john_doe), params: { type: 'MergeRequest' } expect(response.status).to eq(200) expect(response).to include_pagination_headers @@ -73,7 +73,7 @@ describe API::Todos do context 'and using the state filter' do it 'filters based on state param' do - get api('/todos', john_doe), { state: 'done' } + get api('/todos', john_doe), params: { state: 'done' } expect(response.status).to eq(200) expect(response).to include_pagination_headers @@ -84,7 +84,7 @@ describe API::Todos do context 'and using the project filter' do it 'filters based on project_id param' do - get api('/todos', john_doe), { project_id: project_2.id } + get api('/todos', john_doe), params: { project_id: project_2.id } expect(response.status).to eq(200) expect(response).to include_pagination_headers @@ -95,7 +95,7 @@ describe API::Todos do context 'and using the group filter' do it 'filters based on project_id param' do - get api('/todos', john_doe), { group_id: group.id, sort: :target_id } + get api('/todos', john_doe), params: { group_id: group.id, sort: :target_id } expect(response.status).to eq(200) expect(response).to include_pagination_headers @@ -106,7 +106,7 @@ describe API::Todos do context 'and using the action filter' do it 'filters based on action param' do - get api('/todos', john_doe), { action: 'mentioned' } + get api('/todos', john_doe), params: { action: 'mentioned' } expect(response.status).to eq(200) expect(response).to include_pagination_headers diff --git a/spec/requests/api/triggers_spec.rb b/spec/requests/api/triggers_spec.rb index 658df6945d2..15dc901d06e 100644 --- a/spec/requests/api/triggers_spec.rb +++ b/spec/requests/api/triggers_spec.rb @@ -26,13 +26,13 @@ describe API::Triggers do context 'Handles errors' do it 'returns bad request if token is missing' do - post api("/projects/#{project.id}/trigger/pipeline"), ref: 'master' + post api("/projects/#{project.id}/trigger/pipeline"), params: { ref: 'master' } expect(response).to have_gitlab_http_status(400) end it 'returns not found if project is not found' do - post api('/projects/0/trigger/pipeline'), options.merge(ref: 'master') + post api('/projects/0/trigger/pipeline'), params: options.merge(ref: 'master') expect(response).to have_gitlab_http_status(404) end @@ -42,7 +42,7 @@ describe API::Triggers do let(:pipeline) { project.ci_pipelines.last } it 'creates pipeline' do - post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'master') + post api("/projects/#{project.id}/trigger/pipeline"), params: options.merge(ref: 'master') expect(response).to have_gitlab_http_status(201) expect(json_response).to include('id' => pipeline.id) @@ -52,7 +52,7 @@ describe API::Triggers do end it 'returns bad request with no pipeline created if there\'s no commit for that ref' do - post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'other-branch') + post api("/projects/#{project.id}/trigger/pipeline"), params: options.merge(ref: 'other-branch') expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('base' => ["Reference not found"]) @@ -64,21 +64,21 @@ describe API::Triggers do end it 'validates variables to be a hash' do - post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: 'value', ref: 'master') + post api("/projects/#{project.id}/trigger/pipeline"), params: options.merge(variables: 'value', ref: 'master') expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('variables is invalid') end it 'validates variables needs to be a map of key-valued strings' do - post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: { key: %w(1 2) }, ref: 'master') + post api("/projects/#{project.id}/trigger/pipeline"), params: options.merge(variables: { key: %w(1 2) }, ref: 'master') expect(response).to have_gitlab_http_status(400) expect(json_response['message']).to eq('variables needs to be a map of key-valued strings') end it 'creates trigger request with variables' do - post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: variables, ref: 'master') + post api("/projects/#{project.id}/trigger/pipeline"), params: options.merge(variables: variables, ref: 'master') expect(response).to have_gitlab_http_status(201) expect(pipeline.variables.map { |v| { v.key => v.value } }.last).to eq(variables) @@ -91,7 +91,7 @@ describe API::Triggers do end it 'creates pipeline' do - post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'master') + post api("/projects/#{project.id}/trigger/pipeline"), params: options.merge(ref: 'master') expect(response).to have_gitlab_http_status(201) expect(json_response).to include('id' => pipeline.id) @@ -104,14 +104,14 @@ describe API::Triggers do context 'when triggering a pipeline from a trigger token' do it 'does not leak the presence of project when token is for different project' do - post api("/projects/#{project2.id}/ref/master/trigger/pipeline?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' } + post api("/projects/#{project2.id}/ref/master/trigger/pipeline?token=#{trigger_token}"), params: { ref: 'refs/heads/other-branch' } expect(response).to have_gitlab_http_status(404) end it 'creates builds from the ref given in the URL, not in the body' do expect do - post api("/projects/#{project.id}/ref/master/trigger/pipeline?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' } + post api("/projects/#{project.id}/ref/master/trigger/pipeline?token=#{trigger_token}"), params: { ref: 'refs/heads/other-branch' } end.to change(project.builds, :count).by(5) expect(response).to have_gitlab_http_status(201) @@ -122,7 +122,7 @@ describe API::Triggers do project.repository.create_file(user, '.gitlab/gitlabhq/new_feature.md', 'something valid', message: 'new_feature', branch_name: 'v.1-branch') expect do - post api("/projects/#{project.id}/ref/v.1-branch/trigger/pipeline?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' } + post api("/projects/#{project.id}/ref/v.1-branch/trigger/pipeline?token=#{trigger_token}"), params: { ref: 'refs/heads/other-branch' } end.to change(project.builds, :count).by(4) expect(response).to have_gitlab_http_status(201) @@ -199,7 +199,7 @@ describe API::Triggers do it 'creates trigger' do expect do post api("/projects/#{project.id}/triggers", user), - description: 'trigger' + params: { description: 'trigger' } end.to change {project.triggers.count}.by(1) expect(response).to have_gitlab_http_status(201) @@ -219,7 +219,7 @@ describe API::Triggers do context 'authenticated user with invalid permissions' do it 'does not create trigger' do post api("/projects/#{project.id}/triggers", user2), - description: 'trigger' + params: { description: 'trigger' } expect(response).to have_gitlab_http_status(403) end @@ -228,7 +228,7 @@ describe API::Triggers do context 'unauthenticated user' do it 'does not create trigger' do post api("/projects/#{project.id}/triggers"), - description: 'trigger' + params: { description: 'trigger' } expect(response).to have_gitlab_http_status(401) end @@ -241,7 +241,7 @@ describe API::Triggers do it 'updates description' do put api("/projects/#{project.id}/triggers/#{trigger.id}", user), - description: new_description + params: { description: new_description } expect(response).to have_gitlab_http_status(200) expect(json_response).to include('description' => new_description) diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index bb913ae0e79..f3431e0be3d 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -43,7 +43,7 @@ describe API::Users do end it "returns the user when a valid `username` parameter is passed" do - get api("/users"), username: user.username + get api("/users"), params: { username: user.username } expect(response).to match_response_schema('public_api/v4/user/basics') expect(json_response.size).to eq(1) @@ -52,7 +52,7 @@ describe API::Users do end it "returns the user when a valid `username` parameter is passed (case insensitive)" do - get api("/users"), username: user.username.upcase + get api("/users"), params: { username: user.username.upcase } expect(response).to match_response_schema('public_api/v4/user/basics') expect(json_response.size).to eq(1) @@ -61,7 +61,7 @@ describe API::Users do end it "returns an empty response when an invalid `username` parameter is passed" do - get api("/users"), username: 'invalid' + get api("/users"), params: { username: 'invalid' } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -74,7 +74,7 @@ describe API::Users do end it "returns authorization error when the `username` parameter refers to an inaccessible user" do - get api("/users"), username: user.username + get api("/users"), params: { username: user.username } expect(response).to have_gitlab_http_status(403) end @@ -243,7 +243,7 @@ describe API::Users do admin user - get api('/users', admin), { order_by: 'id', sort: 'asc' } + get api('/users', admin), params: { order_by: 'id', sort: 'asc' } expect(response).to match_response_schema('public_api/v4/user/admins') expect(json_response.size).to eq(2) @@ -256,7 +256,7 @@ describe API::Users do user user_with_2fa = create(:user, :two_factor_via_otp) - get api('/users', admin), { two_factor: 'enabled' } + get api('/users', admin), params: { two_factor: 'enabled' } expect(response).to match_response_schema('public_api/v4/user/admins') expect(json_response.size).to eq(1) @@ -264,7 +264,7 @@ describe API::Users do end it 'returns 400 when provided incorrect sort params' do - get api('/users', admin), { order_by: 'magic', sort: 'asc' } + get api('/users', admin), params: { order_by: 'magic', sort: 'asc' } expect(response).to have_gitlab_http_status(400) end @@ -375,12 +375,12 @@ describe API::Users do it "creates user" do expect do - post api("/users", admin), attributes_for(:user, projects_limit: 3) + post api("/users", admin), params: attributes_for(:user, projects_limit: 3) end.to change { User.count }.by(1) end it "creates user with correct attributes" do - post api('/users', admin), attributes_for(:user, admin: true, can_create_group: true) + post api('/users', admin), params: attributes_for(:user, admin: true, can_create_group: true) expect(response).to have_gitlab_http_status(201) user_id = json_response['id'] new_user = User.find(user_id) @@ -393,13 +393,13 @@ describe API::Users do optional_attributes = { confirm: true } attributes = attributes_for(:user).merge(optional_attributes) - post api('/users', admin), attributes + post api('/users', admin), params: attributes expect(response).to have_gitlab_http_status(201) end it "creates non-admin user" do - post api('/users', admin), attributes_for(:user, admin: false, can_create_group: false) + post api('/users', admin), params: attributes_for(:user, admin: false, can_create_group: false) expect(response).to have_gitlab_http_status(201) user_id = json_response['id'] new_user = User.find(user_id) @@ -409,7 +409,7 @@ describe API::Users do end it "creates non-admin users by default" do - post api('/users', admin), attributes_for(:user) + post api('/users', admin), params: attributes_for(:user) expect(response).to have_gitlab_http_status(201) user_id = json_response['id'] new_user = User.find(user_id) @@ -418,12 +418,12 @@ describe API::Users do end it "returns 201 Created on success" do - post api("/users", admin), attributes_for(:user, projects_limit: 3) + post api("/users", admin), params: attributes_for(:user, projects_limit: 3) expect(response).to have_gitlab_http_status(201) end it 'creates non-external users by default' do - post api("/users", admin), attributes_for(:user) + post api("/users", admin), params: attributes_for(:user) expect(response).to have_gitlab_http_status(201) user_id = json_response['id'] @@ -433,7 +433,7 @@ describe API::Users do end it 'allows an external user to be created' do - post api("/users", admin), attributes_for(:user, external: true) + post api("/users", admin), params: attributes_for(:user, external: true) expect(response).to have_gitlab_http_status(201) user_id = json_response['id'] @@ -443,7 +443,7 @@ describe API::Users do end it "creates user with reset password" do - post api('/users', admin), attributes_for(:user, reset_password: true).except(:password) + post api('/users', admin), params: attributes_for(:user, reset_password: true).except(:password) expect(response).to have_gitlab_http_status(201) @@ -455,7 +455,7 @@ describe API::Users do end it "creates user with private profile" do - post api('/users', admin), attributes_for(:user, private_profile: true) + post api('/users', admin), params: attributes_for(:user, private_profile: true) expect(response).to have_gitlab_http_status(201) @@ -468,40 +468,44 @@ describe API::Users do it "does not create user with invalid email" do post api('/users', admin), - email: 'invalid email', - password: 'password', - name: 'test' + params: { + email: 'invalid email', + password: 'password', + name: 'test' + } expect(response).to have_gitlab_http_status(400) end it 'returns 400 error if name not given' do - post api('/users', admin), attributes_for(:user).except(:name) + post api('/users', admin), params: attributes_for(:user).except(:name) expect(response).to have_gitlab_http_status(400) end it 'returns 400 error if password not given' do - post api('/users', admin), attributes_for(:user).except(:password) + post api('/users', admin), params: attributes_for(:user).except(:password) expect(response).to have_gitlab_http_status(400) end it 'returns 400 error if email not given' do - post api('/users', admin), attributes_for(:user).except(:email) + post api('/users', admin), params: attributes_for(:user).except(:email) expect(response).to have_gitlab_http_status(400) end it 'returns 400 error if username not given' do - post api('/users', admin), attributes_for(:user).except(:username) + post api('/users', admin), params: attributes_for(:user).except(:username) expect(response).to have_gitlab_http_status(400) end it 'returns 400 error if user does not validate' do post api('/users', admin), - password: 'pass', - email: 'test@example.com', - username: 'test!', - name: 'test', - bio: 'g' * 256, - projects_limit: -1 + params: { + password: 'pass', + email: 'test@example.com', + username: 'test!', + name: 'test', + bio: 'g' * 256, + projects_limit: -1 + } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['password']) .to eq(['is too short (minimum is 8 characters)']) @@ -514,26 +518,30 @@ describe API::Users do end it "is not available for non admin users" do - post api("/users", user), attributes_for(:user) + post api("/users", user), params: attributes_for(:user) expect(response).to have_gitlab_http_status(403) end context 'with existing user' do before do post api('/users', admin), - email: 'test@example.com', - password: 'password', - username: 'test', - name: 'foo' + params: { + email: 'test@example.com', + password: 'password', + username: 'test', + name: 'foo' + } end it 'returns 409 conflict error if user with same email exists' do expect do post api('/users', admin), - name: 'foo', - email: 'test@example.com', - password: 'password', - username: 'foo' + params: { + name: 'foo', + email: 'test@example.com', + password: 'password', + username: 'foo' + } end.to change { User.count }.by(0) expect(response).to have_gitlab_http_status(409) expect(json_response['message']).to eq('Email has already been taken') @@ -542,10 +550,12 @@ describe API::Users do it 'returns 409 conflict error if same username exists' do expect do post api('/users', admin), - name: 'foo', - email: 'foo@example.com', - password: 'password', - username: 'test' + params: { + name: 'foo', + email: 'foo@example.com', + password: 'password', + username: 'test' + } end.to change { User.count }.by(0) expect(response).to have_gitlab_http_status(409) expect(json_response['message']).to eq('Username has already been taken') @@ -554,17 +564,19 @@ describe API::Users do it 'returns 409 conflict error if same username exists (case insensitive)' do expect do post api('/users', admin), - name: 'foo', - email: 'foo@example.com', - password: 'password', - username: 'TEST' + params: { + name: 'foo', + email: 'foo@example.com', + password: 'password', + username: 'TEST' + } end.to change { User.count }.by(0) expect(response).to have_gitlab_http_status(409) expect(json_response['message']).to eq('Username has already been taken') end it 'creates user with new identity' do - post api("/users", admin), attributes_for(:user, provider: 'github', extern_uid: '67890') + post api("/users", admin), params: attributes_for(:user, provider: 'github', extern_uid: '67890') expect(response).to have_gitlab_http_status(201) expect(json_response['identities'].first['extern_uid']).to eq('67890') @@ -593,7 +605,7 @@ describe API::Users do let!(:admin_user) { create(:admin) } it "updates user with new bio" do - put api("/users/#{user.id}", admin), { bio: 'new test bio' } + put api("/users/#{user.id}", admin), params: { bio: 'new test bio' } expect(response).to have_gitlab_http_status(200) expect(json_response['bio']).to eq('new test bio') @@ -601,14 +613,14 @@ describe API::Users do end it "updates user with new password and forces reset on next login" do - put api("/users/#{user.id}", admin), password: '12345678' + put api("/users/#{user.id}", admin), params: { password: '12345678' } expect(response).to have_gitlab_http_status(200) expect(user.reload.password_expires_at).to be <= Time.now end it "updates user with organization" do - put api("/users/#{user.id}", admin), { organization: 'GitLab' } + put api("/users/#{user.id}", admin), params: { organization: 'GitLab' } expect(response).to have_gitlab_http_status(200) expect(json_response['organization']).to eq('GitLab') @@ -616,7 +628,7 @@ describe API::Users do end it 'updates user with avatar' do - put api("/users/#{user.id}", admin), { avatar: fixture_file_upload('spec/fixtures/banana_sample.gif', 'image/gif') } + put api("/users/#{user.id}", admin), params: { avatar: fixture_file_upload('spec/fixtures/banana_sample.gif', 'image/gif') } user.reload @@ -628,7 +640,7 @@ describe API::Users do it 'updates user with a new email' do old_email = user.email old_notification_email = user.notification_email - put api("/users/#{user.id}", admin), email: 'new@email.com' + put api("/users/#{user.id}", admin), params: { email: 'new@email.com' } user.reload @@ -640,7 +652,7 @@ describe API::Users do end it 'skips reconfirmation when requested' do - put api("/users/#{user.id}", admin), email: 'new@email.com', skip_reconfirmation: true + put api("/users/#{user.id}", admin), params: { email: 'new@email.com', skip_reconfirmation: true } user.reload @@ -650,7 +662,7 @@ describe API::Users do end it 'updates user with his own username' do - put api("/users/#{user.id}", admin), username: user.username + put api("/users/#{user.id}", admin), params: { username: user.username } expect(response).to have_gitlab_http_status(200) expect(json_response['username']).to eq(user.username) @@ -658,14 +670,14 @@ describe API::Users do end it "updates user's existing identity" do - put api("/users/#{omniauth_user.id}", admin), provider: 'ldapmain', extern_uid: '654321' + put api("/users/#{omniauth_user.id}", admin), params: { provider: 'ldapmain', extern_uid: '654321' } expect(response).to have_gitlab_http_status(200) expect(omniauth_user.reload.identities.first.extern_uid).to eq('654321') end it 'updates user with new identity' do - put api("/users/#{user.id}", admin), provider: 'github', extern_uid: 'john' + put api("/users/#{user.id}", admin), params: { provider: 'github', extern_uid: 'john' } expect(response).to have_gitlab_http_status(200) expect(user.reload.identities.first.extern_uid).to eq('john') @@ -673,14 +685,14 @@ describe API::Users do end it "updates admin status" do - put api("/users/#{user.id}", admin), { admin: true } + put api("/users/#{user.id}", admin), params: { admin: true } expect(response).to have_gitlab_http_status(200) expect(user.reload.admin).to eq(true) end it "updates external status" do - put api("/users/#{user.id}", admin), { external: true } + put api("/users/#{user.id}", admin), params: { external: true } expect(response.status).to eq 200 expect(json_response['external']).to eq(true) @@ -688,14 +700,14 @@ describe API::Users do end it "updates private profile" do - put api("/users/#{user.id}", admin), { private_profile: true } + put api("/users/#{user.id}", admin), params: { private_profile: true } expect(response).to have_gitlab_http_status(200) expect(user.reload.private_profile).to eq(true) end it "does not update admin status" do - put api("/users/#{admin_user.id}", admin), { can_create_group: false } + put api("/users/#{admin_user.id}", admin), params: { can_create_group: false } expect(response).to have_gitlab_http_status(200) expect(admin_user.reload.admin).to eq(true) @@ -703,7 +715,7 @@ describe API::Users do end it "does not allow invalid update" do - put api("/users/#{user.id}", admin), { email: 'invalid email' } + put api("/users/#{user.id}", admin), params: { email: 'invalid email' } expect(response).to have_gitlab_http_status(400) expect(user.reload.email).not_to eq('invalid email') @@ -712,7 +724,7 @@ describe API::Users do context 'when the current user is not an admin' do it "is not available" do expect do - put api("/users/#{user.id}", user), attributes_for(:user) + put api("/users/#{user.id}", user), params: attributes_for(:user) end.not_to change { user.reload.attributes } expect(response).to have_gitlab_http_status(403) @@ -720,7 +732,7 @@ describe API::Users do end it "returns 404 for non-existing user" do - put api("/users/999999", admin), { bio: 'update should fail' } + put api("/users/999999", admin), params: { bio: 'update should fail' } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 User Not Found') @@ -734,12 +746,14 @@ describe API::Users do it 'returns 400 error if user does not validate' do put api("/users/#{user.id}", admin), - password: 'pass', - email: 'test@example.com', - username: 'test!', - name: 'test', - bio: 'g' * 256, - projects_limit: -1 + params: { + password: 'pass', + email: 'test@example.com', + username: 'test!', + name: 'test', + bio: 'g' * 256, + projects_limit: -1 + } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['password']) .to eq(['is too short (minimum is 8 characters)']) @@ -752,26 +766,26 @@ describe API::Users do end it 'returns 400 if provider is missing for identity update' do - put api("/users/#{omniauth_user.id}", admin), extern_uid: '654321' + put api("/users/#{omniauth_user.id}", admin), params: { extern_uid: '654321' } expect(response).to have_gitlab_http_status(400) end it 'returns 400 if external UID is missing for identity update' do - put api("/users/#{omniauth_user.id}", admin), provider: 'ldap' + put api("/users/#{omniauth_user.id}", admin), params: { provider: 'ldap' } expect(response).to have_gitlab_http_status(400) end context "with existing user" do before do - post api("/users", admin), { email: 'test@example.com', password: 'password', username: 'test', name: 'test' } - post api("/users", admin), { email: 'foo@bar.com', password: 'password', username: 'john', name: 'john' } + post api("/users", admin), params: { email: 'test@example.com', password: 'password', username: 'test', name: 'test' } + post api("/users", admin), params: { email: 'foo@bar.com', password: 'password', username: 'john', name: 'john' } @user = User.all.last end it 'returns 409 conflict error if email address exists' do - put api("/users/#{@user.id}", admin), email: 'test@example.com' + put api("/users/#{@user.id}", admin), params: { email: 'test@example.com' } expect(response).to have_gitlab_http_status(409) expect(@user.reload.email).to eq(@user.email) @@ -779,7 +793,7 @@ describe API::Users do it 'returns 409 conflict error if username taken' do @user_id = User.all.last.id - put api("/users/#{@user.id}", admin), username: 'test' + put api("/users/#{@user.id}", admin), params: { username: 'test' } expect(response).to have_gitlab_http_status(409) expect(@user.reload.username).to eq(@user.username) @@ -787,7 +801,7 @@ describe API::Users do it 'returns 409 conflict error if username taken (case insensitive)' do @user_id = User.all.last.id - put api("/users/#{@user.id}", admin), username: 'TEST' + put api("/users/#{@user.id}", admin), params: { username: 'TEST' } expect(response).to have_gitlab_http_status(409) expect(@user.reload.username).to eq(@user.username) @@ -801,14 +815,14 @@ describe API::Users do end it "does not create invalid ssh key" do - post api("/users/#{user.id}/keys", admin), { title: "invalid key" } + post api("/users/#{user.id}/keys", admin), params: { title: "invalid key" } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('key is missing') end it 'does not create key without title' do - post api("/users/#{user.id}/keys", admin), key: 'some key' + post api("/users/#{user.id}/keys", admin), params: { key: 'some key' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('title is missing') @@ -817,7 +831,7 @@ describe API::Users do it "creates ssh key" do key_attrs = attributes_for :key expect do - post api("/users/#{user.id}/keys", admin), key_attrs + post api("/users/#{user.id}/keys", admin), params: key_attrs end.to change { user.keys.count }.by(1) end @@ -909,7 +923,7 @@ describe API::Users do it 'creates GPG key' do key_attrs = attributes_for :gpg_key expect do - post api("/users/#{user.id}/gpg_keys", admin), key_attrs + post api("/users/#{user.id}/gpg_keys", admin), params: key_attrs expect(response).to have_gitlab_http_status(201) end.to change { user.gpg_keys.count }.by(1) @@ -1058,7 +1072,7 @@ describe API::Users do end it "does not create invalid email" do - post api("/users/#{user.id}/emails", admin), {} + post api("/users/#{user.id}/emails", admin), params: {} expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('email is missing') @@ -1067,7 +1081,7 @@ describe API::Users do it "creates unverified email" do email_attrs = attributes_for :email expect do - post api("/users/#{user.id}/emails", admin), email_attrs + post api("/users/#{user.id}/emails", admin), params: email_attrs end.to change { user.emails.count }.by(1) email = Email.find_by(user_id: user.id, email: email_attrs[:email]) @@ -1084,7 +1098,7 @@ describe API::Users do email_attrs = attributes_for :email email_attrs[:skip_confirmation] = true - post api("/users/#{user.id}/emails", admin), email_attrs + post api("/users/#{user.id}/emails", admin), params: email_attrs expect(response).to have_gitlab_http_status(201) @@ -1379,32 +1393,32 @@ describe API::Users do it "creates ssh key" do key_attrs = attributes_for :key expect do - post api("/user/keys", user), key_attrs + post api("/user/keys", user), params: key_attrs end.to change { user.keys.count }.by(1) expect(response).to have_gitlab_http_status(201) end it "returns a 401 error if unauthorized" do - post api("/user/keys"), title: 'some title', key: 'some key' + post api("/user/keys"), params: { title: 'some title', key: 'some key' } expect(response).to have_gitlab_http_status(401) end it "does not create ssh key without key" do - post api("/user/keys", user), title: 'title' + post api("/user/keys", user), params: { title: 'title' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('key is missing') end it 'does not create ssh key without title' do - post api('/user/keys', user), key: 'some key' + post api('/user/keys', user), params: { key: 'some key' } expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('title is missing') end it "does not create ssh key without title" do - post api("/user/keys", user), key: "somekey" + post api("/user/keys", user), params: { key: "somekey" } expect(response).to have_gitlab_http_status(400) end end @@ -1523,14 +1537,14 @@ describe API::Users do it 'creates a GPG key' do key_attrs = attributes_for :gpg_key expect do - post api('/user/gpg_keys', user), key_attrs + post api('/user/gpg_keys', user), params: key_attrs expect(response).to have_gitlab_http_status(201) end.to change { user.gpg_keys.count }.by(1) end it 'returns a 401 error if unauthorized' do - post api('/user/gpg_keys'), key: 'some key' + post api('/user/gpg_keys'), params: { key: 'some key' } expect(response).to have_gitlab_http_status(401) end @@ -1685,18 +1699,18 @@ describe API::Users do it "creates email" do email_attrs = attributes_for :email expect do - post api("/user/emails", user), email_attrs + post api("/user/emails", user), params: email_attrs end.to change { user.emails.count }.by(1) expect(response).to have_gitlab_http_status(201) end it "returns a 401 error if unauthorized" do - post api("/user/emails"), email: 'some email' + post api("/user/emails"), params: { email: 'some email' } expect(response).to have_gitlab_http_status(401) end it "does not create email with invalid email" do - post api("/user/emails", user), {} + post api("/user/emails", user), params: {} expect(response).to have_gitlab_http_status(400) expect(json_response['error']).to eq('email is missing') @@ -1864,14 +1878,14 @@ describe API::Users do describe 'PUT /user/status' do it 'saves the status' do - put api('/user/status', user), { emoji: 'smirk', message: 'hello world' } + put api('/user/status', user), params: { emoji: 'smirk', message: 'hello world' } expect(response).to have_gitlab_http_status(:success) expect(json_response['emoji']).to eq('smirk') end it 'renders errors when the status was invalid' do - put api('/user/status', user), { emoji: 'does not exist', message: 'hello world' } + put api('/user/status', user), params: { emoji: 'does not exist', message: 'hello world' } expect(response).to have_gitlab_http_status(400) expect(json_response['message']['emoji']).to be_present @@ -1950,8 +1964,10 @@ describe API::Users do it 'returns a 404 error if user not found' do post api("/users/#{not_existing_user_id}/impersonation_tokens", admin), - name: name, - expires_at: expires_at + params: { + name: name, + expires_at: expires_at + } expect(response).to have_gitlab_http_status(404) expect(json_response['message']).to eq('404 User Not Found') @@ -1959,8 +1975,10 @@ describe API::Users do it 'returns a 403 error when authenticated as normal user' do post api("/users/#{user.id}/impersonation_tokens", user), - name: name, - expires_at: expires_at + params: { + name: name, + expires_at: expires_at + } expect(response).to have_gitlab_http_status(403) expect(json_response['message']).to eq('403 Forbidden') @@ -1968,10 +1986,12 @@ describe API::Users do it 'creates a impersonation token' do post api("/users/#{user.id}/impersonation_tokens", admin), - name: name, - expires_at: expires_at, - scopes: scopes, - impersonation: impersonation + params: { + name: name, + expires_at: expires_at, + scopes: scopes, + impersonation: impersonation + } expect(response).to have_gitlab_http_status(201) expect(json_response['name']).to eq(name) diff --git a/spec/requests/api/variables_spec.rb b/spec/requests/api/variables_spec.rb index be333df1d78..cdac5b2f400 100644 --- a/spec/requests/api/variables_spec.rb +++ b/spec/requests/api/variables_spec.rb @@ -73,7 +73,7 @@ describe API::Variables do context 'authorized user with proper permissions' do it 'creates variable' do expect do - post api("/projects/#{project.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2', protected: true + post api("/projects/#{project.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'VALUE_2', protected: true } end.to change {project.variables.count}.by(1) expect(response).to have_gitlab_http_status(201) @@ -84,7 +84,7 @@ describe API::Variables do it 'creates variable with optional attributes' do expect do - post api("/projects/#{project.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2' + post api("/projects/#{project.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'VALUE_2' } end.to change {project.variables.count}.by(1) expect(response).to have_gitlab_http_status(201) @@ -95,7 +95,7 @@ describe API::Variables do it 'does not allow to duplicate variable key' do expect do - post api("/projects/#{project.id}/variables", user), key: variable.key, value: 'VALUE_2' + post api("/projects/#{project.id}/variables", user), params: { key: variable.key, value: 'VALUE_2' } end.to change {project.variables.count}.by(0) expect(response).to have_gitlab_http_status(400) @@ -125,7 +125,7 @@ describe API::Variables do initial_variable = project.variables.reload.first value_before = initial_variable.value - put api("/projects/#{project.id}/variables/#{variable.key}", user), value: 'VALUE_1_UP', protected: true + put api("/projects/#{project.id}/variables/#{variable.key}", user), params: { value: 'VALUE_1_UP', protected: true } updated_variable = project.variables.reload.first diff --git a/spec/requests/api/wikis_spec.rb b/spec/requests/api/wikis_spec.rb index 08bada44178..f5092e8e2b5 100644 --- a/spec/requests/api/wikis_spec.rb +++ b/spec/requests/api/wikis_spec.rb @@ -39,7 +39,7 @@ describe API::Wikis do end it 'returns the list of wiki pages with content' do - get api(url, user), with_content: 1 + get api(url, user), params: { with_content: 1 } expect(response).to have_gitlab_http_status(200) expect(json_response.size).to eq(2) @@ -74,7 +74,7 @@ describe API::Wikis do shared_examples_for 'creates wiki page' do it 'creates the wiki page' do - post(api(url, user), payload) + post(api(url, user), params: payload) expect(response).to have_gitlab_http_status(201) expect(json_response.size).to eq(4) @@ -89,7 +89,7 @@ describe API::Wikis do it "responds with validation error on empty #{part}" do payload.delete(part) - post(api(url, user), payload) + post(api(url, user), params: payload) expect(response).to have_gitlab_http_status(400) expect(json_response.size).to eq(1) @@ -143,7 +143,7 @@ describe API::Wikis do it 'pushes attachment to the wiki repository' do allow(SecureRandom).to receive(:hex).and_return('fixed_hex') - post(api(url, user), payload) + post(api(url, user), params: payload) expect(response).to have_gitlab_http_status(201) expect(json_response).to eq result_hash.deep_stringify_keys @@ -152,7 +152,7 @@ describe API::Wikis do it 'responds with validation error on empty file' do payload.delete(:file) - post(api(url, user), payload) + post(api(url, user), params: payload) expect(response).to have_gitlab_http_status(400) expect(json_response.size).to eq(1) @@ -162,7 +162,7 @@ describe API::Wikis do it 'responds with validation error on invalid temp file' do payload[:file] = { tempfile: '/etc/hosts' } - post(api(url, user), payload) + post(api(url, user), params: payload) expect(response).to have_gitlab_http_status(400) expect(json_response.size).to eq(1) @@ -395,7 +395,7 @@ describe API::Wikis do context 'when user is guest' do before do - post(api(url), payload) + post(api(url), params: payload) end include_examples '404 Project Not Found' @@ -404,7 +404,7 @@ describe API::Wikis do context 'when user is developer' do before do project.add_developer(user) - post(api(url, user), payload) + post(api(url, user), params: payload) end include_examples '403 Forbidden' @@ -413,7 +413,7 @@ describe API::Wikis do context 'when user is maintainer' do before do project.add_maintainer(user) - post(api(url, user), payload) + post(api(url, user), params: payload) end include_examples '403 Forbidden' @@ -425,7 +425,7 @@ describe API::Wikis do context 'when user is guest' do before do - post(api(url), payload) + post(api(url), params: payload) end include_examples '404 Project Not Found' @@ -453,7 +453,7 @@ describe API::Wikis do context 'when user is guest' do before do - post(api(url), payload) + post(api(url), params: payload) end include_examples '404 Project Not Found' @@ -487,7 +487,7 @@ describe API::Wikis do context 'when user is guest' do before do - put(api(url), payload) + put(api(url), params: payload) end include_examples '404 Project Not Found' @@ -497,7 +497,7 @@ describe API::Wikis do before do project.add_developer(user) - put(api(url, user), payload) + put(api(url, user), params: payload) end include_examples '403 Forbidden' @@ -507,7 +507,7 @@ describe API::Wikis do before do project.add_maintainer(user) - put(api(url, user), payload) + put(api(url, user), params: payload) end include_examples '403 Forbidden' @@ -519,7 +519,7 @@ describe API::Wikis do context 'when user is guest' do before do - put(api(url), payload) + put(api(url), params: payload) end include_examples '404 Project Not Found' @@ -529,7 +529,7 @@ describe API::Wikis do before do project.add_developer(user) - put(api(url, user), payload) + put(api(url, user), params: payload) end include_examples 'updates wiki page' @@ -545,7 +545,7 @@ describe API::Wikis do before do project.add_maintainer(user) - put(api(url, user), payload) + put(api(url, user), params: payload) end include_examples 'updates wiki page' @@ -563,7 +563,7 @@ describe API::Wikis do context 'when user is guest' do before do - put(api(url), payload) + put(api(url), params: payload) end include_examples '404 Project Not Found' @@ -573,7 +573,7 @@ describe API::Wikis do before do project.add_developer(user) - put(api(url, user), payload) + put(api(url, user), params: payload) end include_examples 'updates wiki page' @@ -589,7 +589,7 @@ describe API::Wikis do before do project.add_maintainer(user) - put(api(url, user), payload) + put(api(url, user), params: payload) end include_examples 'updates wiki page' @@ -606,7 +606,7 @@ describe API::Wikis do let(:project) { create(:project, :wiki_repo, namespace: group) } before do - put(api(url, user), payload) + put(api(url, user), params: payload) end include_examples 'updates wiki page' @@ -751,7 +751,7 @@ describe API::Wikis do context 'when user is guest' do before do - post(api(url), payload) + post(api(url), params: payload) end include_examples '404 Project Not Found' @@ -760,7 +760,7 @@ describe API::Wikis do context 'when user is developer' do before do project.add_developer(user) - post(api(url, user), payload) + post(api(url, user), params: payload) end include_examples '403 Forbidden' @@ -769,7 +769,7 @@ describe API::Wikis do context 'when user is maintainer' do before do project.add_maintainer(user) - post(api(url, user), payload) + post(api(url, user), params: payload) end include_examples '403 Forbidden' @@ -781,7 +781,7 @@ describe API::Wikis do context 'when user is guest' do before do - post(api(url), payload) + post(api(url), params: payload) end include_examples '404 Project Not Found' @@ -809,7 +809,7 @@ describe API::Wikis do context 'when user is guest' do before do - post(api(url), payload) + post(api(url), params: payload) end include_examples '404 Project Not Found' diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb index 0dc459d9b5a..939e870ec53 100644 --- a/spec/requests/git_http_spec.rb +++ b/spec/requests/git_http_spec.rb @@ -726,7 +726,7 @@ describe 'Git HTTP requests' do let(:params) { { service: 'git-upload-pack' } } before do - get path, params + get path, params: params end it "redirects to the .git suffix version" do @@ -738,7 +738,7 @@ describe 'Git HTTP requests' do let(:params) { { service: 'git-receive-pack' } } before do - get path, params + get path, params: params end it "redirects to the .git suffix version" do @@ -750,7 +750,7 @@ describe 'Git HTTP requests' do let(:params) { { service: 'git-implode-pack' } } before do - get path, params + get path, params: params end it "redirects to the sign-in page" do diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb index e042d772718..4bb3b848e17 100644 --- a/spec/requests/jwt_controller_spec.rb +++ b/spec/requests/jwt_controller_spec.rb @@ -11,7 +11,7 @@ describe JwtController do end context 'existing service' do - subject! { get '/jwt/auth', parameters } + subject! { get '/jwt/auth', params: parameters } it { expect(response).to have_gitlab_http_status(200) } @@ -29,9 +29,9 @@ describe JwtController do let(:headers) { { authorization: credentials('gitlab-ci-token', build.token) } } context 'project with enabled CI' do - subject! { get '/jwt/auth', parameters, headers } + subject! { get '/jwt/auth', params: parameters, headers: headers } - it { expect(service_class).to have_received(:new).with(project, nil, parameters) } + it { expect(service_class).to have_received(:new).with(project, nil, ActionController::Parameters.new(parameters).permit!) } end context 'project with disabled CI' do @@ -39,7 +39,7 @@ describe JwtController do project.project_feature.update_attribute(:builds_access_level, ProjectFeature::DISABLED) end - subject! { get '/jwt/auth', parameters, headers } + subject! { get '/jwt/auth', params: parameters, headers: headers } it { expect(response).to have_gitlab_http_status(401) } end @@ -53,11 +53,11 @@ describe JwtController do stub_container_registry_config(enabled: true) end - subject! { get '/jwt/auth', parameters, headers } + subject! { get '/jwt/auth', params: parameters, headers: headers } it 'authenticates correctly' do expect(response).to have_gitlab_http_status(200) - expect(service_class).to have_received(:new).with(nil, user, parameters) + expect(service_class).to have_received(:new).with(nil, user, ActionController::Parameters.new(parameters).permit!) end end end @@ -66,9 +66,9 @@ describe JwtController do let(:user) { create(:user) } let(:headers) { { authorization: credentials(user.username, user.password) } } - subject! { get '/jwt/auth', parameters, headers } + subject! { get '/jwt/auth', params: parameters, headers: headers } - it { expect(service_class).to have_received(:new).with(nil, user, parameters) } + it { expect(service_class).to have_received(:new).with(nil, user, ActionController::Parameters.new(parameters).permit!) } context 'when passing a flat array of scopes' do # We use this trick to make rails to generate a query_string: @@ -83,7 +83,7 @@ describe JwtController do end let(:service_parameters) do - { service: service_name, scopes: %w(scope1 scope2) } + ActionController::Parameters.new({ service: service_name, scopes: %w(scope1 scope2) }).permit! end it { expect(service_class).to have_received(:new).with(nil, user, service_parameters) } @@ -115,7 +115,7 @@ describe JwtController do context 'when internal auth is enabled' do it 'rejects the authorization attempt' do - get '/jwt/auth', parameters, headers + get '/jwt/auth', params: parameters, headers: headers expect(response).to have_gitlab_http_status(401) expect(response.body).not_to include('You must use a personal access token with \'api\' scope for Git over HTTP') @@ -125,7 +125,7 @@ describe JwtController do context 'when internal auth is disabled' do it 'rejects the authorization attempt with personal access token message' do allow_any_instance_of(ApplicationSetting).to receive(:password_authentication_enabled_for_git?) { false } - get '/jwt/auth', parameters, headers + get '/jwt/auth', params: parameters, headers: headers expect(response).to have_gitlab_http_status(401) expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP') @@ -136,7 +136,7 @@ describe JwtController do context 'when using unauthenticated request' do it 'accepts the authorization attempt' do - get '/jwt/auth', parameters + get '/jwt/auth', params: parameters expect(response).to have_gitlab_http_status(200) end @@ -144,12 +144,12 @@ describe JwtController do it 'allows read access' do expect(service).to receive(:execute).with(authentication_abilities: Gitlab::Auth.read_authentication_abilities) - get '/jwt/auth', parameters + get '/jwt/auth', params: parameters end end context 'unknown service' do - subject! { get '/jwt/auth', service: 'unknown' } + subject! { get '/jwt/auth', params: { service: 'unknown' } } it { expect(response).to have_gitlab_http_status(404) } end diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb index e349181b794..3cc29a7076d 100644 --- a/spec/requests/lfs_http_spec.rb +++ b/spec/requests/lfs_http_spec.rb @@ -79,7 +79,7 @@ describe 'Git LFS API and storage' do end it 'responds with a 501 message on download' do - get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers + get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", params: {}, headers: headers expect(response).to have_gitlab_http_status(501) end @@ -97,7 +97,7 @@ describe 'Git LFS API and storage' do end it 'responds with a 501 message on download' do - get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers + get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", params: {}, headers: headers expect(response).to have_gitlab_http_status(501) end @@ -123,7 +123,7 @@ describe 'Git LFS API and storage' do end it 'responds with a 403 message on download' do - get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers + get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", params: {}, headers: headers expect(response).to have_gitlab_http_status(403) expect(json_response).to include('message' => 'Access forbidden. Check your access level.') @@ -143,7 +143,7 @@ describe 'Git LFS API and storage' do end it 'responds with a 200 message on download' do - get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers + get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", params: {}, headers: headers expect(response).to have_gitlab_http_status(200) end @@ -172,7 +172,7 @@ describe 'Git LFS API and storage' do let(:authorization) { authorize_user } before do - get "#{project.http_url_to_repo}/info/lfs/objects/#{sample_oid}", nil, headers + get "#{project.http_url_to_repo}/info/lfs/objects/#{sample_oid}", params: {}, headers: headers end it_behaves_like 'a deprecated' @@ -197,7 +197,7 @@ describe 'Git LFS API and storage' do enable_lfs update_permissions before_get - get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers + get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", params: {}, headers: headers end context 'and request comes from gitlab-workhorse' do @@ -1347,8 +1347,9 @@ describe 'Git LFS API and storage' do context 'when pushing the same lfs object to the second project' do before do - put "#{second_project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}/#{sample_size}", nil, - headers.merge('X-Gitlab-Lfs-Tmp' => lfs_tmp_file).compact + put "#{second_project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}/#{sample_size}", + params: {}, + headers: headers.merge('X-Gitlab-Lfs-Tmp' => lfs_tmp_file).compact end it 'responds with status 200' do @@ -1366,7 +1367,7 @@ describe 'Git LFS API and storage' do authorize_headers = headers authorize_headers.merge!(workhorse_internal_api_request_header) if verified - put "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}/#{sample_size}/authorize", nil, authorize_headers + put "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}/#{sample_size}/authorize", params: {}, headers: authorize_headers end def put_finalize(lfs_tmp = lfs_tmp_file, with_tempfile: false, args: {}) @@ -1387,7 +1388,7 @@ describe 'Git LFS API and storage' do end def put_finalize_with_args(args) - put "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}/#{sample_size}", args, headers + put "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}/#{sample_size}", params: args, headers: headers end def lfs_tmp_file @@ -1420,7 +1421,10 @@ describe 'Git LFS API and storage' do end def post_lfs_json(url, body = nil, headers = nil) - post(url, body.try(:to_json), (headers || {}).merge('Content-Type' => LfsRequest::CONTENT_TYPE)) + params = body.try(:to_json) + headers = (headers || {}).merge('Content-Type' => LfsRequest::CONTENT_TYPE) + + post(url, params: params, headers: headers) end def json_response diff --git a/spec/requests/lfs_locks_api_spec.rb b/spec/requests/lfs_locks_api_spec.rb index a44b43a591f..28cb90e450e 100644 --- a/spec/requests/lfs_locks_api_spec.rb +++ b/spec/requests/lfs_locks_api_spec.rb @@ -146,11 +146,11 @@ describe 'Git LFS File Locking API' do end def post_lfs_json(url, body = nil, headers = nil) - post(url, body.try(:to_json), (headers || {}).merge('Content-Type' => LfsRequest::CONTENT_TYPE)) + post(url, params: body.try(:to_json), headers: (headers || {}).merge('Content-Type' => LfsRequest::CONTENT_TYPE)) end def do_get(url, params = nil, headers = nil) - get(url, (params || {}), (headers || {}).merge('Content-Type' => LfsRequest::CONTENT_TYPE)) + get(url, params: (params || {}), headers: (headers || {}).merge('Content-Type' => LfsRequest::CONTENT_TYPE)) end def json_response diff --git a/spec/requests/oauth_tokens_spec.rb b/spec/requests/oauth_tokens_spec.rb index 000c3a2b868..3873e754060 100644 --- a/spec/requests/oauth_tokens_spec.rb +++ b/spec/requests/oauth_tokens_spec.rb @@ -6,11 +6,13 @@ describe 'OAuth Tokens requests' do def request_access_token(user) post '/oauth/token', - grant_type: 'authorization_code', - code: generate_access_grant(user).token, - redirect_uri: application.redirect_uri, - client_id: application.uid, - client_secret: application.secret + params: { + grant_type: 'authorization_code', + code: generate_access_grant(user).token, + redirect_uri: application.redirect_uri, + client_id: application.uid, + client_secret: application.secret + } end def generate_access_grant(user) diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb index b1cf7a531f4..2b148c1b563 100644 --- a/spec/requests/openid_connect_spec.rb +++ b/spec/requests/openid_connect_spec.rb @@ -47,15 +47,17 @@ describe 'OpenID Connect requests' do login_as user post '/oauth/token', - grant_type: 'authorization_code', - code: access_grant.token, - redirect_uri: application.redirect_uri, - client_id: application.uid, - client_secret: application.secret + params: { + grant_type: 'authorization_code', + code: access_grant.token, + redirect_uri: application.redirect_uri, + client_id: application.uid, + client_secret: application.secret + } end def request_user_info! - get '/oauth/userinfo', nil, 'Authorization' => "Bearer #{access_token.token}" + get '/oauth/userinfo', params: {}, headers: { 'Authorization' => "Bearer #{access_token.token}" } end context 'Application without OpenID scope' do @@ -102,7 +104,7 @@ describe 'OpenID Connect requests' do expect(json_response).to match(id_token_claims.merge(user_info_claims)) expected_groups = [group1.full_path, group3.full_path] - expected_groups << group4.full_path if Group.supports_nested_groups? + expected_groups << group4.full_path if Group.supports_nested_objects? expect(json_response['groups']).to match_array(expected_groups) end diff --git a/spec/requests/rack_attack_global_spec.rb b/spec/requests/rack_attack_global_spec.rb index c0a3ea397df..49021f5d1b7 100644 --- a/spec/requests/rack_attack_global_spec.rb +++ b/spec/requests/rack_attack_global_spec.rb @@ -177,7 +177,7 @@ describe 'Rack Attack global throttles' do context 'when the request is to the api internal endpoints' do it 'allows requests over the rate limit' do (1 + requests_per_period).times do - get url_api_internal, secret_token: Gitlab::Shell.secret_token + get url_api_internal, params: { secret_token: Gitlab::Shell.secret_token } expect(response).to have_http_status 200 end end @@ -345,7 +345,7 @@ describe 'Rack Attack global throttles' do end def api_get_args_with_token_headers(partial_url, token_headers) - ["/api/#{API::API.version}#{partial_url}", nil, token_headers] + ["/api/#{API::API.version}#{partial_url}", params: nil, headers: token_headers] end def rss_url(user) diff --git a/spec/requests/request_profiler_spec.rb b/spec/requests/request_profiler_spec.rb index 9afeb2983b0..284a51fcc32 100644 --- a/spec/requests/request_profiler_spec.rb +++ b/spec/requests/request_profiler_spec.rb @@ -18,7 +18,7 @@ describe 'Request Profiler' do path = "/#{project.full_path}" Timecop.freeze(time) do - get path, nil, 'X-Profile-Token' => Gitlab::RequestProfiler.profile_token + get path, params: {}, headers: { 'X-Profile-Token' => Gitlab::RequestProfiler.profile_token } end profile_path = "#{Gitlab.config.shared.path}/tmp/requests_profiles/#{path.tr('/', '|')}_#{time.to_i}.html" diff --git a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb new file mode 100644 index 00000000000..08ffc3c3a53 --- /dev/null +++ b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'rubocop' +require 'rubocop/rspec/support' +require_relative '../../../rubocop/cop/inject_enterprise_edition_module' + +describe RuboCop::Cop::InjectEnterpriseEditionModule do + include CopHelper + + subject(:cop) { described_class.new } + + it 'flags the use of `prepend EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + prepend EE::Foo + ^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `prepend ::EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + prepend ::EE::Foo + ^^^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `include EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + include EE::Foo + ^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `include ::EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + include ::EE::Foo + ^^^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `extend EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + extend EE::Foo + ^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `extend ::EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + extend ::EE::Foo + ^^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'does not flag prepending of regular modules' do + expect_no_offenses(<<~SOURCE) + class Foo + prepend Foo + end + SOURCE + end + + it 'does not flag including of regular modules' do + expect_no_offenses(<<~SOURCE) + class Foo + include Foo + end + SOURCE + end + + it 'does not flag extending using regular modules' do + expect_no_offenses(<<~SOURCE) + class Foo + extend Foo + end + SOURCE + end + + it 'does not flag the use of `prepend EE` on the last line' do + expect_no_offenses(<<~SOURCE) + class Foo + end + + Foo.prepend(EE::Foo) + SOURCE + end + + it 'does not flag the use of `include EE` on the last line' do + expect_no_offenses(<<~SOURCE) + class Foo + end + + Foo.include(EE::Foo) + SOURCE + end + + it 'does not flag the use of `extend EE` on the last line' do + expect_no_offenses(<<~SOURCE) + class Foo + end + + Foo.extend(EE::Foo) + SOURCE + end + + it 'autocorrects offenses by just disabling the Cop' do + source = <<~SOURCE + class Foo + prepend EE::Foo + include Bar + end + SOURCE + + expect(autocorrect_source(source)).to eq(<<~SOURCE) + class Foo + prepend EE::Foo # rubocop: disable Cop/InjectEnterpriseEditionModule + include Bar + end + SOURCE + end +end diff --git a/spec/rubocop/cop/migration/add_timestamps_spec.rb b/spec/rubocop/cop/migration/add_timestamps_spec.rb index 3a41c91add2..fae0177d5f5 100644 --- a/spec/rubocop/cop/migration/add_timestamps_spec.rb +++ b/spec/rubocop/cop/migration/add_timestamps_spec.rb @@ -11,7 +11,7 @@ describe RuboCop::Cop::Migration::AddTimestamps do subject(:cop) { described_class.new } let(:migration_with_add_timestamps) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change @@ -24,7 +24,7 @@ describe RuboCop::Cop::Migration::AddTimestamps do let(:migration_without_add_timestamps) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change @@ -36,7 +36,7 @@ describe RuboCop::Cop::Migration::AddTimestamps do let(:migration_with_add_timestamps_with_timezone) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change diff --git a/spec/rubocop/cop/migration/datetime_spec.rb b/spec/rubocop/cop/migration/datetime_spec.rb index 9e844325371..f2d9483d8d3 100644 --- a/spec/rubocop/cop/migration/datetime_spec.rb +++ b/spec/rubocop/cop/migration/datetime_spec.rb @@ -12,7 +12,7 @@ describe RuboCop::Cop::Migration::Datetime do let(:migration_with_datetime) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change @@ -25,7 +25,7 @@ describe RuboCop::Cop::Migration::Datetime do let(:migration_with_timestamp) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change @@ -38,7 +38,7 @@ describe RuboCop::Cop::Migration::Datetime do let(:migration_without_datetime) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change @@ -50,7 +50,7 @@ describe RuboCop::Cop::Migration::Datetime do let(:migration_with_datetime_with_timezone) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change diff --git a/spec/rubocop/cop/migration/timestamps_spec.rb b/spec/rubocop/cop/migration/timestamps_spec.rb index 685bdb21803..1812818692a 100644 --- a/spec/rubocop/cop/migration/timestamps_spec.rb +++ b/spec/rubocop/cop/migration/timestamps_spec.rb @@ -11,7 +11,7 @@ describe RuboCop::Cop::Migration::Timestamps do subject(:cop) { described_class.new } let(:migration_with_timestamps) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change @@ -27,7 +27,7 @@ describe RuboCop::Cop::Migration::Timestamps do let(:migration_without_timestamps) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change @@ -42,7 +42,7 @@ describe RuboCop::Cop::Migration::Timestamps do let(:migration_with_timestamps_with_timezone) do %q( - class Users < ActiveRecord::Migration + class Users < ActiveRecord::Migration[4.2] DOWNTIME = false def change diff --git a/spec/serializers/entity_date_helper_spec.rb b/spec/serializers/entity_date_helper_spec.rb index 36da8d33a44..ae0f917415c 100644 --- a/spec/serializers/entity_date_helper_spec.rb +++ b/spec/serializers/entity_date_helper_spec.rb @@ -50,7 +50,7 @@ describe EntityDateHelper do end context 'when less than 31 days remaining' do - let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, due_date: 12.days.from_now.utc)) } + let(:milestone_remaining) { date_helper_class.remaining_days_in_words(12.days.from_now.utc.to_date) } it 'returns days remaining' do expect(milestone_remaining).to eq("<strong>12</strong> days remaining") @@ -58,7 +58,7 @@ describe EntityDateHelper do end context 'when less than 1 year and more than 30 days remaining' do - let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, due_date: 2.months.from_now.utc)) } + let(:milestone_remaining) { date_helper_class.remaining_days_in_words(2.months.from_now.utc.to_date) } it 'returns months remaining' do expect(milestone_remaining).to eq("<strong>2</strong> months remaining") @@ -66,7 +66,7 @@ describe EntityDateHelper do end context 'when more than 1 year remaining' do - let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, due_date: (1.year.from_now + 2.days).utc)) } + let(:milestone_remaining) { date_helper_class.remaining_days_in_words((1.year.from_now + 2.days).utc.to_date) } it 'returns years remaining' do expect(milestone_remaining).to eq("<strong>1</strong> year remaining") @@ -74,7 +74,7 @@ describe EntityDateHelper do end context 'when milestone is expired' do - let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, due_date: 2.days.ago.utc)) } + let(:milestone_remaining) { date_helper_class.remaining_days_in_words(2.days.ago.utc.to_date) } it 'returns "Past due"' do expect(milestone_remaining).to eq("<strong>Past due</strong>") @@ -82,7 +82,7 @@ describe EntityDateHelper do end context 'when milestone has start_date in the future' do - let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, start_date: 2.days.from_now.utc)) } + let(:milestone_remaining) { date_helper_class.remaining_days_in_words(nil, 2.days.from_now.utc.to_date) } it 'returns "Upcoming"' do expect(milestone_remaining).to eq("<strong>Upcoming</strong>") @@ -90,7 +90,7 @@ describe EntityDateHelper do end context 'when milestone has start_date in the past' do - let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, start_date: 2.days.ago.utc)) } + let(:milestone_remaining) { date_helper_class.remaining_days_in_words(nil, 2.days.ago.utc.to_date) } it 'returns days elapsed' do expect(milestone_remaining).to eq("<strong>2</strong> days elapsed") diff --git a/spec/serializers/environment_entity_spec.rb b/spec/serializers/environment_entity_spec.rb index b7324a26ed2..791b64dc356 100644 --- a/spec/serializers/environment_entity_spec.rb +++ b/spec/serializers/environment_entity_spec.rb @@ -40,4 +40,34 @@ describe EnvironmentEntity do expect(subject).to include(:metrics_path) end end + + context 'with deployment platform' do + let(:project) { create(:project, :repository) } + let(:environment) { create(:environment, project: project) } + + context 'when deployment platform is a cluster' do + before do + create(:cluster, + :provided_by_gcp, + :project, + environment_scope: '*', + projects: [project]) + end + + it 'should include cluster_type' do + expect(subject).to include(:cluster_type) + expect(subject[:cluster_type]).to eq('project_type') + end + end + + context 'when deployment platform is a Kubernetes Service' do + before do + create(:kubernetes_service, project: project) + end + + it 'should not include cluster_type' do + expect(subject).not_to include(:cluster_type) + end + end + end end diff --git a/spec/serializers/issue_board_entity_spec.rb b/spec/serializers/issue_board_entity_spec.rb index 06d9d3657e6..f6fa2a794f6 100644 --- a/spec/serializers/issue_board_entity_spec.rb +++ b/spec/serializers/issue_board_entity_spec.rb @@ -3,21 +3,40 @@ require 'spec_helper' describe IssueBoardEntity do - let(:project) { create(:project) } - let(:resource) { create(:issue, project: project) } - let(:user) { create(:user) } - - let(:request) { double('request', current_user: user) } + let(:project) { create(:project) } + let(:resource) { create(:issue, project: project) } + let(:user) { create(:user) } + let(:milestone) { create(:milestone, project: project) } + let(:label) { create(:label, project: project, title: 'Test Label') } + let(:request) { double('request', current_user: user) } subject { described_class.new(resource, request: request).as_json } it 'has basic attributes' do expect(subject).to include(:id, :iid, :title, :confidential, :due_date, :project_id, :relative_position, - :project, :labels) + :labels, :assignees, project: hash_including(:id, :path)) end it 'has path and endpoints' do expect(subject).to include(:reference_path, :real_path, :issue_sidebar_endpoint, :toggle_subscription_endpoint, :assignable_labels_endpoint) end + + it 'has milestone attributes' do + resource.milestone = milestone + + expect(subject).to include(milestone: hash_including(:id, :title)) + end + + it 'has assignee attributes' do + resource.assignees = [user] + + expect(subject).to include(assignees: array_including(hash_including(:id, :name, :username, :avatar_url))) + end + + it 'has label attributes' do + resource.labels = [label] + + expect(subject).to include(labels: array_including(hash_including(:id, :title, :color, :description, :text_color, :priority))) + end end diff --git a/spec/serializers/issue_serializer_spec.rb b/spec/serializers/issue_serializer_spec.rb index e8c46c0cdee..b8255e004d0 100644 --- a/spec/serializers/issue_serializer_spec.rb +++ b/spec/serializers/issue_serializer_spec.rb @@ -20,11 +20,19 @@ describe IssueSerializer do context 'sidebar issue serialization' do let(:serializer) { 'sidebar' } - it 'matches sidebar issue json schema' do + it 'matches issue_sidebar json schema' do expect(json_entity).to match_schema('entities/issue_sidebar') end end + context 'sidebar extras issue serialization' do + let(:serializer) { 'sidebar_extras' } + + it 'matches issue_sidebar_extras json schema' do + expect(json_entity).to match_schema('entities/issue_sidebar_extras') + end + end + context 'board issue serialization' do let(:serializer) { 'board' } diff --git a/spec/serializers/merge_request_basic_serializer_spec.rb b/spec/serializers/merge_request_basic_serializer_spec.rb deleted file mode 100644 index 1fad8e6bc5d..00000000000 --- a/spec/serializers/merge_request_basic_serializer_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'spec_helper' - -describe MergeRequestBasicSerializer do - let(:resource) { create(:merge_request) } - let(:user) { create(:user) } - - let(:json_entity) do - described_class.new(current_user: user) - .represent(resource, serializer: 'basic') - .with_indifferent_access - end - - it 'matches basic merge request json' do - expect(json_entity).to match_schema('entities/merge_request_basic') - end -end diff --git a/spec/serializers/merge_request_serializer_spec.rb b/spec/serializers/merge_request_serializer_spec.rb index b259cb92962..276e0f6ff3d 100644 --- a/spec/serializers/merge_request_serializer_spec.rb +++ b/spec/serializers/merge_request_serializer_spec.rb @@ -20,8 +20,16 @@ describe MergeRequestSerializer do context 'sidebar merge request serialization' do let(:serializer) { 'sidebar' } - it 'matches basic merge request json schema' do - expect(json_entity).to match_schema('entities/merge_request_basic') + it 'matches merge_request_sidebar json schema' do + expect(json_entity).to match_schema('entities/merge_request_sidebar') + end + end + + context 'sidebar_extras merge request serialization' do + let(:serializer) { 'sidebar_extras' } + + it 'matches merge_request_sidebar_extras json schema' do + expect(json_entity).to match_schema('entities/merge_request_sidebar_extras') end end diff --git a/spec/serializers/suggestion_entity_spec.rb b/spec/serializers/suggestion_entity_spec.rb new file mode 100644 index 00000000000..047571f161c --- /dev/null +++ b/spec/serializers/suggestion_entity_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe SuggestionEntity do + include RepoHelpers + + let(:user) { create(:user) } + let(:request) { double('request', current_user: user) } + let(:suggestion) { create(:suggestion) } + let(:entity) { described_class.new(suggestion, request: request) } + + subject { entity.as_json } + + it 'exposes correct attributes' do + expect(subject).to include(:id, :from_original_line, :to_original_line, :from_line, + :to_line, :appliable, :applied, :from_content, :to_content) + end + + it 'exposes current user abilities' do + expect(subject[:current_user]).to include(:can_apply) + end +end diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb index f2e9799452a..8021bd338e0 100644 --- a/spec/services/auth/container_registry_authentication_service_spec.rb +++ b/spec/services/auth/container_registry_authentication_service_spec.rb @@ -5,7 +5,7 @@ describe Auth::ContainerRegistryAuthenticationService do let(:current_user) { nil } let(:current_params) { {} } let(:rsa_key) { OpenSSL::PKey::RSA.generate(512) } - let(:payload) { JWT.decode(subject[:token], rsa_key).first } + let(:payload) { JWT.decode(subject[:token], rsa_key, true, { algorithm: 'RS256' }).first } let(:authentication_abilities) do [:read_container_image, :create_container_image, :admin_container_image] diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index 8b8021ecbc8..ffa47d527f7 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -840,6 +840,37 @@ describe Ci::CreatePipelineService do end end + context "when config uses variables for only keyword" do + let(:config) do + { + build: { + stage: 'build', + script: 'echo', + only: { + variables: %w($CI) + } + } + } + end + + context 'when merge request is specified' do + let(:merge_request) do + create(:merge_request, + source_project: project, + source_branch: ref_name, + target_project: project, + target_branch: 'master') + end + + it 'does not create a merge request pipeline' do + expect(pipeline).not_to be_persisted + + expect(pipeline.errors[:base]) + .to eq(['No stages / jobs for this pipeline.']) + end + end + end + context "when config has 'except: [tags]'" do let(:config) do { diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb index 56e2a405bcd..9d65ac15213 100644 --- a/spec/services/ci/register_job_service_spec.rb +++ b/spec/services/ci/register_job_service_spec.rb @@ -244,7 +244,9 @@ module Ci context 'when first build is stalled' do before do - pending_job.update(lock_version: 0) + allow_any_instance_of(Ci::RegisterJobService).to receive(:assign_runner!).and_call_original + allow_any_instance_of(Ci::RegisterJobService).to receive(:assign_runner!) + .with(pending_job, anything).and_raise(ActiveRecord::StaleObjectError) end subject { described_class.new(specific_runner).execute } diff --git a/spec/services/clusters/gcp/finalize_creation_service_spec.rb b/spec/services/clusters/gcp/finalize_creation_service_spec.rb index d69678c1277..2664649df47 100644 --- a/spec/services/clusters/gcp/finalize_creation_service_spec.rb +++ b/spec/services/clusters/gcp/finalize_creation_service_spec.rb @@ -20,7 +20,7 @@ describe Clusters::Gcp::FinalizeCreationService, '#execute' do subject { described_class.new.execute(provider) } before do - allow(ClusterPlatformConfigureWorker).to receive(:perform_async) + allow(ClusterConfigureWorker).to receive(:perform_async) end shared_examples 'success' do @@ -43,8 +43,8 @@ describe Clusters::Gcp::FinalizeCreationService, '#execute' do expect(platform.token).to eq(token) end - it 'calls ClusterPlatformConfigureWorker in a ascync fashion' do - expect(ClusterPlatformConfigureWorker).to receive(:perform_async).with(cluster.id) + it 'calls ClusterConfigureWorker in a ascync fashion' do + expect(ClusterConfigureWorker).to receive(:perform_async).with(cluster.id) subject end diff --git a/spec/services/clusters/update_service_spec.rb b/spec/services/clusters/update_service_spec.rb index 73f9be242a3..b2e6ebecd4a 100644 --- a/spec/services/clusters/update_service_spec.rb +++ b/spec/services/clusters/update_service_spec.rb @@ -37,7 +37,7 @@ describe Clusters::UpdateService do end before do - allow(ClusterPlatformConfigureWorker).to receive(:perform_async) + allow(ClusterConfigureWorker).to receive(:perform_async) stub_kubeclient_get_namespace('https://kubernetes.example.com', namespace: 'my-namespace') end diff --git a/spec/services/create_release_service_spec.rb b/spec/services/create_release_service_spec.rb deleted file mode 100644 index ac0a0458f56..00000000000 --- a/spec/services/create_release_service_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' - -describe CreateReleaseService do - let(:project) { create(:project, :repository) } - let(:user) { create(:user) } - let(:tag_name) { project.repository.tag_names.first } - let(:description) { 'Awesome release!' } - let(:service) { described_class.new(project, user) } - - it 'creates a new release' do - result = service.execute(tag_name, description) - expect(result[:status]).to eq(:success) - release = project.releases.find_by(tag: tag_name) - expect(release).not_to be_nil - expect(release.description).to eq(description) - end - - it 'raises an error if the tag does not exist' do - result = service.execute("foobar", description) - expect(result[:status]).to eq(:error) - end - - context 'there already exists a release on a tag' do - before do - service.execute(tag_name, description) - end - - it 'raises an error and does not update the release' do - result = service.execute(tag_name, 'The best release!') - expect(result[:status]).to eq(:error) - expect(project.releases.find_by(tag: tag_name).description).to eq(description) - end - end -end diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb index 224e933bebc..fe6a8691ae0 100644 --- a/spec/services/groups/create_service_spec.rb +++ b/spec/services/groups/create_service_spec.rb @@ -55,7 +55,7 @@ describe Groups::CreateService, '#execute' do context 'when nested groups feature is disabled' do it 'does not save group and returns an error' do - allow(Group).to receive(:supports_nested_groups?).and_return(false) + allow(Group).to receive(:supports_nested_objects?).and_return(false) is_expected.not_to be_persisted expect(subject.errors[:parent_id]).to include('You don’t have permission to create a subgroup in this group.') @@ -66,7 +66,7 @@ describe Groups::CreateService, '#execute' do context 'when nested groups feature is enabled' do before do - allow(Group).to receive(:supports_nested_groups?).and_return(true) + allow(Group).to receive(:supports_nested_objects?).and_return(true) end context 'as guest' do diff --git a/spec/services/groups/nested_create_service_spec.rb b/spec/services/groups/nested_create_service_spec.rb index 86fdd43c1e5..75d6ddb0a2c 100644 --- a/spec/services/groups/nested_create_service_spec.rb +++ b/spec/services/groups/nested_create_service_spec.rb @@ -30,7 +30,7 @@ describe Groups::NestedCreateService do let(:params) { { group_path: 'a-group' } } before do - allow(Group).to receive(:supports_nested_groups?) { false } + allow(Group).to receive(:supports_nested_objects?) { false } end it 'creates the group' do diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb index dd8a1cee074..6b48c993c57 100644 --- a/spec/services/groups/transfer_service_spec.rb +++ b/spec/services/groups/transfer_service_spec.rb @@ -9,7 +9,7 @@ describe Groups::TransferService, :postgresql do shared_examples 'ensuring allowed transfer for a group' do context 'with other database than PostgreSQL' do before do - allow(Group).to receive(:supports_nested_groups?).and_return(false) + allow(Group).to receive(:supports_nested_objects?).and_return(false) end it 'should return false' do diff --git a/spec/services/groups/update_service_spec.rb b/spec/services/groups/update_service_spec.rb index 84cfa53ea05..d87a7dd234d 100644 --- a/spec/services/groups/update_service_spec.rb +++ b/spec/services/groups/update_service_spec.rb @@ -56,7 +56,7 @@ describe Groups::UpdateService do create(:project, :private, group: internal_group) expect(TodosDestroyer::GroupPrivateWorker).to receive(:perform_in) - .with(1.hour, internal_group.id) + .with(Todo::WAIT_FOR_DELETE, internal_group.id) end it "changes permission level to private" do diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb index f0b0f7956ce..ca366cdf1df 100644 --- a/spec/services/issuable/bulk_update_service_spec.rb +++ b/spec/services/issuable/bulk_update_service_spec.rb @@ -28,6 +28,33 @@ describe Issuable::BulkUpdateService do expect(project.issues.opened).to be_empty expect(project.issues.closed).not_to be_empty end + + context 'when issue for a different project is created' do + let(:private_project) { create(:project, :private) } + let(:issue) { create(:issue, project: private_project, author: user) } + + context 'when user has access to the project' do + it 'closes all issues passed' do + private_project.add_maintainer(user) + + bulk_update(issues + [issue], state_event: 'close') + + expect(project.issues.opened).to be_empty + expect(project.issues.closed).not_to be_empty + expect(private_project.issues.closed).not_to be_empty + end + end + + context 'when user does not have access to project' do + it 'only closes all issues that the user has access to' do + bulk_update(issues + [issue], state_event: 'close') + + expect(project.issues.opened).to be_empty + expect(project.issues.closed).not_to be_empty + expect(private_project.issues.closed).to be_empty + end + end + end end describe 'reopen issues' do diff --git a/spec/services/issuable/common_system_notes_service_spec.rb b/spec/services/issuable/common_system_notes_service_spec.rb index fa1a421d528..fa5d5ebac5c 100644 --- a/spec/services/issuable/common_system_notes_service_spec.rb +++ b/spec/services/issuable/common_system_notes_service_spec.rb @@ -5,7 +5,7 @@ describe Issuable::CommonSystemNotesService do let(:project) { create(:project) } let(:issuable) { create(:issue) } - describe '#execute' do + context 'on issuable update' do it_behaves_like 'system note creation', { title: 'New title' }, 'changed title' it_behaves_like 'system note creation', { description: 'New description' }, 'changed the description' it_behaves_like 'system note creation', { discussion_locked: true }, 'locked this issue' @@ -20,7 +20,7 @@ describe Issuable::CommonSystemNotesService do end it 'creates a resource label event' do - described_class.new(project, user).execute(issuable, []) + described_class.new(project, user).execute(issuable, old_labels: []) event = issuable.reload.resource_label_events.last expect(event).not_to be_nil @@ -68,4 +68,47 @@ describe Issuable::CommonSystemNotesService do end end end + + context 'on issuable create' do + let(:issuable) { build(:issue) } + + subject { described_class.new(project, user).execute(issuable, old_labels: [], is_update: false) } + + it 'does not create system note for title and description' do + issuable.save + + expect { subject }.not_to change { issuable.notes.count } + end + + it 'creates a resource label event for labels added' do + label = create(:label, project: project) + + issuable.labels << label + issuable.save + + expect { subject }.to change { issuable.resource_label_events.count }.from(0).to(1) + + event = issuable.reload.resource_label_events.last + + expect(event).not_to be_nil + expect(event.label_id).to eq label.id + expect(event.user_id).to eq user.id + end + + it 'creates a system note for milestone set' do + issuable.milestone = create(:milestone, project: project) + issuable.save + + expect { subject }.to change { issuable.notes.count }.from(0).to(1) + expect(issuable.notes.last.note).to match('changed milestone') + end + + it 'creates a system note for due_date set' do + issuable.due_date = Date.today + issuable.save + + expect { subject }.to change { issuable.notes.count }.from(0).to(1) + expect(issuable.notes.last.note).to match('changed due date') + end + end end diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index bd519e7f077..ce20bf2bef6 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -77,7 +77,7 @@ describe Issues::UpdateService, :mailer do end it 'enqueues ConfidentialIssueWorker when an issue is made confidential' do - expect(TodosDestroyer::ConfidentialIssueWorker).to receive(:perform_in).with(1.hour, issue.id) + expect(TodosDestroyer::ConfidentialIssueWorker).to receive(:perform_in).with(Todo::WAIT_FOR_DELETE, issue.id) update_issue(confidential: true) end diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb index 0a5220c7c61..5aa7165e135 100644 --- a/spec/services/members/destroy_service_spec.rb +++ b/spec/services/members/destroy_service_spec.rb @@ -22,7 +22,7 @@ describe Members::DestroyService do shared_examples 'a service destroying a member' do before do type = member.is_a?(GroupMember) ? 'Group' : 'Project' - expect(TodosDestroyer::EntityLeaveWorker).to receive(:perform_in).with(1.hour, member.user_id, member.source_id, type) + expect(TodosDestroyer::EntityLeaveWorker).to receive(:perform_in).with(Todo::WAIT_FOR_DELETE, member.user_id, member.source_id, type) end it 'destroys the member' do diff --git a/spec/services/members/update_service_spec.rb b/spec/services/members/update_service_spec.rb index 6d19a95ffeb..599ed39ca37 100644 --- a/spec/services/members/update_service_spec.rb +++ b/spec/services/members/update_service_spec.rb @@ -20,11 +20,28 @@ describe Members::UpdateService do shared_examples 'a service updating a member' do it 'updates the member' do + expect(TodosDestroyer::EntityLeaveWorker).not_to receive(:perform_in).with(Todo::WAIT_FOR_DELETE, member.user_id, member.source_id, source.class.name) + updated_member = described_class.new(current_user, params).execute(member, permission: permission) expect(updated_member).to be_valid expect(updated_member.access_level).to eq(Gitlab::Access::MAINTAINER) end + + context 'when member is downgraded to guest' do + let(:params) do + { access_level: Gitlab::Access::GUEST } + end + + it 'schedules to delete confidential todos' do + expect(TodosDestroyer::EntityLeaveWorker).to receive(:perform_in).with(Todo::WAIT_FOR_DELETE, member.user_id, member.source_id, source.class.name).once + + updated_member = described_class.new(current_user, params).execute(member, permission: permission) + + expect(updated_member).to be_valid + expect(updated_member.access_level).to eq(Gitlab::Access::GUEST) + end + end end before do diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb index 1894d8c8d0e..536d0d345a4 100644 --- a/spec/services/merge_requests/build_service_spec.rb +++ b/spec/services/merge_requests/build_service_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' describe MergeRequests::BuildService do using RSpec::Parameterized::TableSyntax include RepoHelpers + include ProjectForksHelper let(:project) { create(:project, :repository) } let(:source_project) { nil } @@ -49,7 +50,7 @@ describe MergeRequests::BuildService do describe '#execute' do it 'calls the compare service with the correct arguments' do - allow_any_instance_of(described_class).to receive(:branches_valid?).and_return(true) + allow_any_instance_of(described_class).to receive(:projects_and_branches_valid?).and_return(true) expect(CompareService).to receive(:new) .with(project, Gitlab::Git::BRANCH_REF_PREFIX + source_branch) .and_call_original @@ -393,11 +394,27 @@ describe MergeRequests::BuildService do end end + context 'target_project is set but repo is not accessible by current_user' do + let(:target_project) do + create(:project, :public, :repository, repository_access_level: ProjectFeature::PRIVATE) + end + + it 'sets target project correctly' do + expect(merge_request.target_project).to eq(project) + end + end + context 'source_project is set and accessible by current_user' do let(:source_project) { create(:project, :public, :repository)} let(:commits) { Commit.decorate([commit_1], project) } - it 'sets target project correctly' do + before do + # To create merge requests _from_ a project the user needs at least + # developer access + source_project.add_developer(user) + end + + it 'sets source project correctly' do expect(merge_request.source_project).to eq(source_project) end end @@ -406,11 +423,43 @@ describe MergeRequests::BuildService do let(:source_project) { create(:project, :private, :repository)} let(:commits) { Commit.decorate([commit_1], project) } - it 'sets target project correctly' do + it 'sets source project correctly' do + expect(merge_request.source_project).to eq(project) + end + end + + context 'source_project is set but the user cannot create merge requests from the project' do + let(:source_project) do + create(:project, :public, :repository, merge_requests_access_level: ProjectFeature::PRIVATE) + end + + it 'sets the source_project correctly' do expect(merge_request.source_project).to eq(project) end end + context 'target_project is not in the fork network of source_project' do + let(:target_project) { create(:project, :public, :repository) } + + it 'adds an error to the merge request' do + expect(merge_request.errors[:validate_fork]).to contain_exactly('Source project is not a fork of the target project') + end + end + + context 'target_project is in the fork network of source project but no longer accessible' do + let!(:project) { fork_project(target_project, user, namespace: user.namespace, repository: true) } + let(:source_project) { project } + let(:target_project) { create(:project, :public, :repository) } + + before do + target_project.update(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + end + + it 'sets the target_project correctly' do + expect(merge_request.target_project).to eq(project) + end + end + context 'when specifying target branch in the description' do let(:description) { "A merge request targeting another branch\n\n/target_branch with-codeowners" } diff --git a/spec/services/notes/update_service_spec.rb b/spec/services/notes/update_service_spec.rb index 533dcdcd6cd..fd9bff46a06 100644 --- a/spec/services/notes/update_service_spec.rb +++ b/spec/services/notes/update_service_spec.rb @@ -20,6 +20,29 @@ describe Notes::UpdateService do @note.reload end + context 'suggestions' do + it 'refreshes note suggestions' do + markdown = <<-MARKDOWN.strip_heredoc + ```suggestion + foo + ``` + + ```suggestion + bar + ``` + MARKDOWN + + suggestion = create(:suggestion) + note = suggestion.note + + expect { described_class.new(project, user, note: markdown).execute(note) } + .to change { note.suggestions.count }.from(1).to(2) + + expect(note.suggestions.order(:relative_order).map(&:to_content)) + .to eq([" foo\n", " bar\n"]) + end + end + context 'todos' do let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) } diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 0f6c2604984..d20e712d365 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -2167,6 +2167,39 @@ describe NotificationService, :mailer do end end + context 'Remote mirror notifications' do + describe '#remote_mirror_update_failed' do + let(:project) { create(:project) } + let(:remote_mirror) { create(:remote_mirror, project: project) } + let(:u_blocked) { create(:user, :blocked) } + let(:u_silence) { create_user_with_notification(:disabled, 'silent-maintainer', project) } + let(:u_owner) { project.owner } + let(:u_maintainer1) { create(:user) } + let(:u_maintainer2) { create(:user) } + let(:u_developer) { create(:user) } + + before do + project.add_maintainer(u_blocked) + project.add_maintainer(u_silence) + project.add_maintainer(u_maintainer1) + project.add_maintainer(u_maintainer2) + project.add_developer(u_developer) + + # Mock remote update + allow(project.repository).to receive(:async_remove_remote) + allow(project.repository).to receive(:add_remote) + + reset_delivered_emails! + end + + it 'emails current watching maintainers' do + notification.remote_mirror_update_failed(remote_mirror) + + should_only_email(u_maintainer1, u_maintainer2, u_owner) + end + end + end + def build_team(project) @u_watcher = create_global_setting_for(create(:user), :watch) @u_participating = create_global_setting_for(create(:user), :participating) @@ -2217,7 +2250,7 @@ describe NotificationService, :mailer do # Creates a nested group only if supported # to avoid errors on MySQL def create_nested_group - if Group.supports_nested_groups? + if Group.supports_nested_objects? parent_group = create(:group, :public) child_group = create(:group, :public, parent: parent_group) @@ -2244,7 +2277,7 @@ describe NotificationService, :mailer do end def add_member_for_parent_group(user, project) - return unless Group.supports_nested_groups? + return unless Group.supports_nested_objects? project.reload @@ -2252,13 +2285,13 @@ describe NotificationService, :mailer do end def should_email_nested_group_user(user, times: 1, recipients: email_recipients) - return unless Group.supports_nested_groups? + return unless Group.supports_nested_objects? should_email(user, times: 1, recipients: email_recipients) end def should_not_email_nested_group_user(user, recipients: email_recipients) - return unless Group.supports_nested_groups? + return unless Group.supports_nested_objects? should_not_email(user, recipients: email_recipients) end diff --git a/spec/services/preview_markdown_service_spec.rb b/spec/services/preview_markdown_service_spec.rb index b69977c812a..458cb8f1f31 100644 --- a/spec/services/preview_markdown_service_spec.rb +++ b/spec/services/preview_markdown_service_spec.rb @@ -19,6 +19,31 @@ describe PreviewMarkdownService do end end + describe 'suggestions' do + let(:params) { { text: "```suggestion\nfoo\n```", preview_suggestions: preview_suggestions } } + let(:service) { described_class.new(project, user, params) } + + context 'when preview markdown param is present' do + let(:preview_suggestions) { true } + + it 'returns users referenced in text' do + result = service.execute + + expect(result[:suggestions]).to eq(['foo']) + end + end + + context 'when preview markdown param is not present' do + let(:preview_suggestions) { false } + + it 'returns users referenced in text' do + result = service.execute + + expect(result[:suggestions]).to eq([]) + end + end + end + context 'new note with quick actions' do let(:issue) { create(:issue, project: project) } let(:params) do diff --git a/spec/services/projects/after_rename_service_spec.rb b/spec/services/projects/after_rename_service_spec.rb index b4718a07204..59c08b30f9f 100644 --- a/spec/services/projects/after_rename_service_spec.rb +++ b/spec/services/projects/after_rename_service_spec.rb @@ -99,6 +99,17 @@ describe Projects::AfterRenameService do expect(rugged_config['gitlab.fullpath']).to eq(project.full_path) end + + it 'updates storage location' do + allow(project_storage).to receive(:rename_repo).and_return(true) + + described_class.new(project).execute + + expect(project.project_repository).to have_attributes( + disk_path: project.disk_path, + shard_name: project.repository_storage + ) + end end context 'using hashed storage' do @@ -193,6 +204,15 @@ describe Projects::AfterRenameService do expect(rugged_config['gitlab.fullpath']).to eq(project.full_path) end + + it 'updates storage location' do + described_class.new(project).execute + + expect(project.project_repository).to have_attributes( + disk_path: project.disk_path, + shard_name: project.repository_storage + ) + end end end end diff --git a/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb b/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb index 6af5bfc7689..95c9b6e63b8 100644 --- a/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb +++ b/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb @@ -4,17 +4,15 @@ describe Projects::LfsPointers::LfsDownloadService do let(:project) { create(:project) } let(:oid) { '9e548e25631dd9ce6b43afd6359ab76da2819d6a5b474e66118c7819e1d8b3e8' } let(:download_link) { "http://gitlab.com/#{oid}" } - let(:lfs_content) do - <<~HEREDOC - whatever - HEREDOC - end + let(:lfs_content) { SecureRandom.random_bytes(10) } subject { described_class.new(project) } before do allow(project).to receive(:lfs_enabled?).and_return(true) WebMock.stub_request(:get, download_link).to_return(body: lfs_content) + + allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_hooks_and_services?).and_return(false) end describe '#execute' do @@ -32,7 +30,7 @@ describe Projects::LfsPointers::LfsDownloadService do it 'stores the content' do subject.execute(oid, download_link) - expect(File.read(LfsObject.first.file.file.file)).to eq lfs_content + expect(File.binread(LfsObject.first.file.file.file)).to eq lfs_content end end @@ -54,6 +52,61 @@ describe Projects::LfsPointers::LfsDownloadService do end end + context 'when localhost requests are allowed' do + let(:download_link) { 'http://192.168.2.120' } + + before do + allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_hooks_and_services?).and_return(true) + end + + it 'downloads the file' do + expect(subject).to receive(:download_and_save_file).and_call_original + + expect { subject.execute(oid, download_link) }.to change { LfsObject.count }.by(1) + end + end + + context 'when a bad URL is used' do + where(download_link: ['/etc/passwd', 'ftp://example.com', 'http://127.0.0.2', 'http://192.168.2.120']) + + with_them do + it 'does not download the file' do + expect { subject.execute(oid, download_link) }.not_to change { LfsObject.count } + end + end + end + + context 'when the URL points to a redirected URL' do + context 'that is blocked' do + where(redirect_link: ['ftp://example.com', 'http://127.0.0.2', 'http://192.168.2.120']) + + with_them do + before do + WebMock.stub_request(:get, download_link).to_return(status: 301, headers: { 'Location' => redirect_link }) + end + + it 'does not follow the redirection' do + expect(Rails.logger).to receive(:error).with(/LFS file with oid #{oid} couldn't be downloaded/) + + expect { subject.execute(oid, download_link) }.not_to change { LfsObject.count } + end + end + end + + context 'that is valid' do + let(:redirect_link) { "http://example.com/"} + + before do + WebMock.stub_request(:get, download_link).to_return(status: 301, headers: { 'Location' => redirect_link }) + WebMock.stub_request(:get, redirect_link).to_return(body: lfs_content) + end + + it 'follows the redirection' do + expect { subject.execute(oid, download_link) }.to change { LfsObject.count }.from(0).to(1) + end + end + end + context 'when an lfs object with the same oid already exists' do before do create(:lfs_object, oid: 'oid') diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 132ad9a2646..766276fdba3 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -63,6 +63,15 @@ describe Projects::TransferService do expect(rugged_config['gitlab.fullpath']).to eq "#{group.full_path}/#{project.path}" end + it 'updates storage location' do + transfer_project(project, user, group) + + expect(project.project_repository).to have_attributes( + disk_path: "#{group.full_path}/#{project.path}", + shard_name: project.repository_storage + ) + end + context 'new group has a kubernetes cluster' do let(:group_cluster) { create(:cluster, :group, :provided_by_gcp) } let(:group) { group_cluster.group } @@ -139,6 +148,17 @@ describe Projects::TransferService do expect(service).not_to receive(:execute_system_hooks) end end + + it 'does not update storage location' do + create(:project_repository, project: project) + + attempt_project_transfer + + expect(project.project_repository).to have_attributes( + disk_path: project.disk_path, + shard_name: project.repository_storage + ) + end end context 'namespace -> no namespace' do diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb index d58ff2cedc0..8adfc63222e 100644 --- a/spec/services/projects/update_service_spec.rb +++ b/spec/services/projects/update_service_spec.rb @@ -41,7 +41,7 @@ describe Projects::UpdateService do end it 'updates the project to private' do - expect(TodosDestroyer::ProjectPrivateWorker).to receive(:perform_in).with(1.hour, project.id) + expect(TodosDestroyer::ProjectPrivateWorker).to receive(:perform_in).with(Todo::WAIT_FOR_DELETE, project.id) result = update_project(project, user, visibility_level: Gitlab::VisibilityLevel::PRIVATE) @@ -191,7 +191,7 @@ describe Projects::UpdateService do context 'when changing feature visibility to private' do it 'updates the visibility correctly' do expect(TodosDestroyer::PrivateFeaturesWorker) - .to receive(:perform_in).with(1.hour, project.id) + .to receive(:perform_in).with(Todo::WAIT_FOR_DELETE, project.id) result = update_project(project, user, project_feature_attributes: { issues_access_level: ProjectFeature::PRIVATE } diff --git a/spec/services/releases/create_service_spec.rb b/spec/services/releases/create_service_spec.rb new file mode 100644 index 00000000000..612e9f152e7 --- /dev/null +++ b/spec/services/releases/create_service_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper' + +describe Releases::CreateService do + let(:project) { create(:project, :repository) } + let(:user) { create(:user) } + let(:tag_name) { project.repository.tag_names.first } + let(:tag_sha) { project.repository.find_tag(tag_name).dereferenced_target.sha } + let(:name) { 'Bionic Beaver' } + let(:description) { 'Awesome release!' } + let(:params) { { tag: tag_name, name: name, description: description, ref: ref } } + let(:ref) { nil } + let(:service) { described_class.new(project, user, params) } + + before do + project.add_maintainer(user) + end + + describe '#execute' do + shared_examples 'a successful release creation' do + it 'creates a new release' do + result = service.execute + expect(result[:status]).to eq(:success) + expect(result[:tag]).not_to be_nil + expect(result[:release]).not_to be_nil + expect(result[:release].description).to eq(description) + expect(result[:release].name).to eq(name) + expect(result[:release].author).to eq(user) + expect(result[:release].sha).to eq(tag_sha) + end + end + + it_behaves_like 'a successful release creation' + + context 'when the tag does not exist' do + let(:tag_name) { 'non-exist-tag' } + + it 'raises an error' do + result = service.execute + + expect(result[:status]).to eq(:error) + end + end + + context 'when ref is provided' do + let(:ref) { 'master' } + let(:tag_name) { 'foobar' } + + it_behaves_like 'a successful release creation' + + it 'creates a tag if the tag does not exist' do + expect(project.repository.ref_exists?("refs/tags/#{tag_name}")).to be_falsey + + result = service.execute + expect(result[:status]).to eq(:success) + expect(result[:tag]).not_to be_nil + expect(result[:release]).not_to be_nil + end + end + + context 'there already exists a release on a tag' do + let!(:release) do + create(:release, project: project, tag: tag_name, description: description) + end + + it 'raises an error and does not update the release' do + result = service.execute + expect(result[:status]).to eq(:error) + expect(project.releases.find_by(tag: tag_name).description).to eq(description) + end + end + end +end diff --git a/spec/services/releases/destroy_service_spec.rb b/spec/services/releases/destroy_service_spec.rb new file mode 100644 index 00000000000..dd5b8708f36 --- /dev/null +++ b/spec/services/releases/destroy_service_spec.rb @@ -0,0 +1,61 @@ +require 'spec_helper' + +describe Releases::DestroyService do + let(:project) { create(:project, :repository) } + let(:mainatiner) { create(:user) } + let(:repoter) { create(:user) } + let(:tag) { 'v1.1.0' } + let!(:release) { create(:release, project: project, tag: tag) } + let(:service) { described_class.new(project, user, params) } + let(:params) { { tag: tag } } + let(:user) { mainatiner } + + before do + project.add_maintainer(mainatiner) + project.add_reporter(repoter) + end + + describe '#execute' do + subject { service.execute } + + context 'when there is a release' do + it 'removes the release' do + expect { subject }.to change { project.releases.count }.by(-1) + end + + it 'returns the destroyed object' do + is_expected.to include(status: :success, release: release) + end + end + + context 'when tag is not found' do + let(:tag) { 'v1.1.1' } + + it 'returns an error' do + is_expected.to include(status: :error, + message: 'Tag does not exist', + http_status: 404) + end + end + + context 'when release is not found' do + let!(:release) { } + + it 'returns an error' do + is_expected.to include(status: :error, + message: 'Release does not exist', + http_status: 404) + end + end + + context 'when user does not have permission' do + let(:user) { repoter } + + it 'returns an error' do + is_expected.to include(status: :error, + message: 'Access Denied', + http_status: 403) + end + end + end +end diff --git a/spec/services/releases/update_service_spec.rb b/spec/services/releases/update_service_spec.rb new file mode 100644 index 00000000000..6c68f364739 --- /dev/null +++ b/spec/services/releases/update_service_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' + +describe Releases::UpdateService do + let(:project) { create(:project, :repository) } + let(:user) { create(:user) } + let(:new_name) { 'A new name' } + let(:new_description) { 'The best release!' } + let(:params) { { name: new_name, description: new_description, tag: tag_name } } + let(:service) { described_class.new(project, user, params) } + let!(:release) { create(:release, project: project, author: user, tag: tag_name) } + let(:tag_name) { 'v1.1.0' } + + before do + project.add_developer(user) + end + + describe '#execute' do + shared_examples 'a failed update' do + it 'raises an error' do + result = service.execute + expect(result[:status]).to eq(:error) + end + end + + it 'successfully updates an existing release' do + result = service.execute + expect(result[:status]).to eq(:success) + expect(result[:release].name).to eq(new_name) + expect(result[:release].description).to eq(new_description) + end + + context 'when the tag does not exists' do + let(:tag_name) { 'foobar' } + + it_behaves_like 'a failed update' + end + + context 'when the release does not exist' do + let!(:release) { } + + it_behaves_like 'a failed update' + end + + context 'with an invalid update' do + let(:new_description) { '' } + + it_behaves_like 'a failed update' + end + end +end diff --git a/spec/services/suggestions/apply_service_spec.rb b/spec/services/suggestions/apply_service_spec.rb new file mode 100644 index 00000000000..3a483717756 --- /dev/null +++ b/spec/services/suggestions/apply_service_spec.rb @@ -0,0 +1,229 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Suggestions::ApplyService do + include ProjectForksHelper + + let(:project) { create(:project, :repository) } + let(:user) { create(:user, :commit_email) } + + let(:position) do + Gitlab::Diff::Position.new(old_path: "files/ruby/popen.rb", + new_path: "files/ruby/popen.rb", + old_line: nil, + new_line: 9, + diff_refs: merge_request.diff_refs) + end + + let(:suggestion) do + create(:suggestion, note: diff_note, + from_content: " raise RuntimeError, \"System commands must be given as an array of strings\"\n", + to_content: " raise RuntimeError, 'Explosion'\n # explosion?\n") + end + + subject { described_class.new(user) } + + context 'patch is appliable' do + let(:expected_content) do + <<-CONTENT.strip_heredoc + require 'fileutils' + require 'open3' + + module Popen + extend self + + def popen(cmd, path=nil) + unless cmd.is_a?(Array) + raise RuntimeError, 'Explosion' + # explosion? + end + + path ||= Dir.pwd + + vars = { + "PWD" => path + } + + options = { + chdir: path + } + + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + + @cmd_output = "" + @cmd_status = 0 + + Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| + @cmd_output << stdout.read + @cmd_output << stderr.read + @cmd_status = wait_thr.value.exitstatus + end + + return @cmd_output, @cmd_status + end + end + CONTENT + end + + context 'non-fork project' do + let(:merge_request) do + create(:merge_request, source_project: project, + target_project: project) + end + + let!(:diff_note) do + create(:diff_note_on_merge_request, noteable: merge_request, + position: position, + project: project) + end + + before do + project.add_maintainer(user) + end + + it 'updates the file with the new contents' do + subject.execute(suggestion) + + blob = project.repository.blob_at_branch(merge_request.source_branch, + position.new_path) + + expect(blob.data).to eq(expected_content) + end + + it 'returns success status' do + result = subject.execute(suggestion) + + expect(result[:status]).to eq(:success) + end + + it 'updates suggestion applied and commit_id columns' do + expect { subject.execute(suggestion) } + .to change(suggestion, :applied) + .from(false).to(true) + .and change(suggestion, :commit_id) + .from(nil) + end + + it 'created commit has users email and name' do + subject.execute(suggestion) + + commit = project.repository.commit + + expect(user.commit_email).not_to eq(user.email) + expect(commit.author_email).to eq(user.commit_email) + expect(commit.committer_email).to eq(user.commit_email) + expect(commit.author_name).to eq(user.name) + end + end + + context 'fork-project' do + let(:project) { create(:project, :public, :repository) } + + let(:forked_project) do + fork_project_with_submodules(project, user) + end + + let(:merge_request) do + create(:merge_request, + source_branch: 'conflict-resolvable-fork', source_project: forked_project, + target_branch: 'conflict-start', target_project: project) + end + + let!(:diff_note) do + create(:diff_note_on_merge_request, noteable: merge_request, position: position, project: project) + end + + before do + project.add_maintainer(user) + end + + it 'updates file in the source project' do + expect(Files::UpdateService).to receive(:new) + .with(merge_request.source_project, user, anything) + .and_call_original + + subject.execute(suggestion) + end + end + end + + context 'no permission' do + let(:merge_request) do + create(:merge_request, source_project: project, + target_project: project) + end + + let(:diff_note) do + create(:diff_note_on_merge_request, noteable: merge_request, + position: position, + project: project) + end + + context 'user cannot write in project repo' do + before do + project.add_reporter(user) + end + + it 'returns error' do + result = subject.execute(suggestion) + + expect(result).to eq(message: "You are not allowed to push into this branch", + status: :error) + end + end + end + + context 'patch is not appliable' do + let(:merge_request) do + create(:merge_request, source_project: project, + target_project: project) + end + + let(:diff_note) do + create(:diff_note_on_merge_request, noteable: merge_request, + position: position, + project: project) + end + + before do + project.add_maintainer(user) + end + + context 'suggestion was already applied' do + it 'returns success status' do + result = subject.execute(suggestion) + + expect(result[:status]).to eq(:success) + end + end + + context 'note is outdated' do + before do + allow(diff_note).to receive(:active?) { false } + end + + it 'returns error message' do + result = subject.execute(suggestion) + + expect(result).to eq(message: 'Suggestion is not appliable', + status: :error) + end + end + + context 'suggestion was already applied' do + before do + suggestion.update!(applied: true, commit_id: 'sha') + end + + it 'returns error message' do + result = subject.execute(suggestion) + + expect(result).to eq(message: 'Suggestion is not appliable', + status: :error) + end + end + end +end diff --git a/spec/services/suggestions/create_service_spec.rb b/spec/services/suggestions/create_service_spec.rb new file mode 100644 index 00000000000..f1142c88a69 --- /dev/null +++ b/spec/services/suggestions/create_service_spec.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Suggestions::CreateService do + let(:project_with_repo) { create(:project, :repository) } + let(:merge_request) do + create(:merge_request, source_project: project_with_repo, + target_project: project_with_repo) + end + + let(:position) do + Gitlab::Diff::Position.new(old_path: "files/ruby/popen.rb", + new_path: "files/ruby/popen.rb", + old_line: nil, + new_line: 14, + diff_refs: merge_request.diff_refs) + end + + let(:markdown) do + <<-MARKDOWN.strip_heredoc + ```suggestion + foo + bar + ``` + + ``` + nothing + ``` + + ```suggestion + xpto + baz + ``` + + ```thing + this is not a suggestion, it's a thing + ``` + MARKDOWN + end + + subject { described_class.new(note) } + + describe '#execute' do + context 'should not try to parse suggestions' do + context 'when not a diff note for merge requests' do + let(:note) do + create(:diff_note_on_commit, project: project_with_repo, + note: markdown) + end + + it 'does not try to parse suggestions' do + expect(Banzai::SuggestionsParser).not_to receive(:parse) + + subject.execute + end + end + + context 'when diff note is not for text' do + let(:note) do + create(:diff_note_on_merge_request, project: project_with_repo, + noteable: merge_request, + position: position, + note: markdown) + end + + it 'does not try to parse suggestions' do + allow(note).to receive(:on_text?) { false } + + expect(Banzai::SuggestionsParser).not_to receive(:parse) + + subject.execute + end + end + end + + context 'should create suggestions' do + let(:note) do + create(:diff_note_on_merge_request, project: project_with_repo, + noteable: merge_request, + position: position, + note: markdown) + end + + context 'single line suggestions' do + it 'persists suggestion records' do + expect { subject.execute } + .to change { note.suggestions.count } + .from(0) + .to(2) + end + + it 'persists original from_content lines and suggested lines' do + subject.execute + + suggestions = note.suggestions.order(:relative_order) + + suggestion_1 = suggestions.first + suggestion_2 = suggestions.last + + expect(suggestion_1).to have_attributes(from_content: " vars = {\n", + to_content: " foo\n bar\n") + + expect(suggestion_2).to have_attributes(from_content: " vars = {\n", + to_content: " xpto\n baz\n") + end + end + end + end +end diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index c52515aefd8..253f2e44d10 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -19,6 +19,7 @@ describe TodoService do before do project.add_guest(guest) project.add_developer(author) + project.add_developer(assignee) project.add_developer(member) project.add_developer(john_doe) project.add_developer(skipped) diff --git a/spec/services/update_release_service_spec.rb b/spec/services/update_release_service_spec.rb deleted file mode 100644 index dc2d0e2d47a..00000000000 --- a/spec/services/update_release_service_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' - -describe UpdateReleaseService do - let(:project) { create(:project, :repository) } - let(:user) { create(:user) } - let(:tag_name) { project.repository.tag_names.first } - let(:description) { 'Awesome release!' } - let(:new_description) { 'The best release!' } - let(:service) { described_class.new(project, user) } - - context 'with an existing release' do - let(:create_service) { CreateReleaseService.new(project, user) } - - before do - create_service.execute(tag_name, description) - end - - it 'successfully updates an existing release' do - result = service.execute(tag_name, new_description) - expect(result[:status]).to eq(:success) - expect(project.releases.find_by(tag: tag_name).description).to eq(new_description) - end - end - - it 'raises an error if the tag does not exist' do - result = service.execute("foobar", description) - expect(result[:status]).to eq(:error) - end - - it 'raises an error if the release does not exist' do - result = service.execute(tag_name, description) - expect(result[:status]).to eq(:error) - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3fedb9ed48c..89357056c93 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -115,7 +115,7 @@ RSpec.configure do |config| TestEnv.clean_test_path end - config.before(:example) do + config.before do # Enable all features by default for testing allow(Feature).to receive(:enabled?) { true } @@ -136,11 +136,11 @@ RSpec.configure do |config| RequestStore.clear! end - config.after(:example) do + config.after do Fog.unmock! if Fog.mock? end - config.after(:example) do + config.after do Gitlab::CurrentSettings.clear_in_memory_application_settings! end @@ -216,15 +216,19 @@ RSpec.configure do |config| # Each example may call `migrate!`, so we must ensure we are migrated down every time config.before(:each, :migration) do + use_fake_application_settings + schema_migrate_down! end config.after(:context, :migration) do schema_migrate_up! + + Gitlab::CurrentSettings.clear_in_memory_application_settings! end config.around(:each, :nested_groups) do |example| - example.run if Group.supports_nested_groups? + example.run if Group.supports_nested_objects? end config.around(:each, :postgresql) do |example| @@ -235,10 +239,6 @@ RSpec.configure do |config| example.run if Gitlab::Database.mysql? end - config.around(:each, :rails5) do |example| - example.run if Gitlab.rails5? - end - # This makes sure the `ApplicationController#can?` method is stubbed with the # original implementation for all view specs. config.before(:each, type: :view) do diff --git a/spec/support/api/boards_shared_examples.rb b/spec/support/api/boards_shared_examples.rb index 943c1f6ffd7..592962ebf7c 100644 --- a/spec/support/api/boards_shared_examples.rb +++ b/spec/support/api/boards_shared_examples.rb @@ -88,7 +88,7 @@ shared_examples_for 'group and project boards' do |route_definition, ee = false| let(:url) { "#{root_url}/#{board.id}/lists" } it 'creates a new issue board list for labels' do - post api(url, user), label_id: ux_label.id + post api(url, user), params: { label_id: ux_label.id } expect(response).to have_gitlab_http_status(201) expect(json_response['label']['name']).to eq(ux_label.title) @@ -96,13 +96,13 @@ shared_examples_for 'group and project boards' do |route_definition, ee = false| end it 'returns 400 when creating a new list if label_id is invalid' do - post api(url, user), label_id: 23423 + post api(url, user), params: { label_id: 23423 } expect(response).to have_gitlab_http_status(400) end it 'returns 403 for members with guest role' do - put api("#{url}/#{test_list.id}", guest), position: 1 + put api("#{url}/#{test_list.id}", guest), params: { position: 1 } expect(response).to have_gitlab_http_status(403) end @@ -112,23 +112,20 @@ shared_examples_for 'group and project boards' do |route_definition, ee = false| let(:url) { "#{root_url}/#{board.id}/lists" } it "updates a list" do - put api("#{url}/#{test_list.id}", user), - position: 1 + put api("#{url}/#{test_list.id}", user), params: { position: 1 } expect(response).to have_gitlab_http_status(200) expect(json_response['position']).to eq(1) end it "returns 404 error if list id not found" do - put api("#{url}/44444", user), - position: 1 + put api("#{url}/44444", user), params: { position: 1 } expect(response).to have_gitlab_http_status(404) end it "returns 403 for members with guest role" do - put api("#{url}/#{test_list.id}", guest), - position: 1 + put api("#{url}/#{test_list.id}", guest), params: { position: 1 } expect(response).to have_gitlab_http_status(403) end diff --git a/spec/support/api/milestones_shared_examples.rb b/spec/support/api/milestones_shared_examples.rb index 3bebb7aae90..5f709831ce1 100644 --- a/spec/support/api/milestones_shared_examples.rb +++ b/spec/support/api/milestones_shared_examples.rb @@ -45,7 +45,7 @@ shared_examples_for 'group and project milestones' do |route_definition| it 'returns an array of milestones specified by iids' do other_milestone = create(:milestone, project: try(:project), group: try(:group)) - get api(route, user), iids: [closed_milestone.iid, other_milestone.iid] + get api(route, user), params: { iids: [closed_milestone.iid, other_milestone.iid] } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -54,7 +54,7 @@ shared_examples_for 'group and project milestones' do |route_definition| end it 'does not return any milestone if none found' do - get api(route, user), iids: [Milestone.maximum(:iid).succ] + get api(route, user), params: { iids: [Milestone.maximum(:iid).succ] } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -73,7 +73,7 @@ shared_examples_for 'group and project milestones' do |route_definition| end it 'returns a milestone by searching for title' do - get api(route, user), search: 'version2' + get api(route, user), params: { search: 'version2' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -83,7 +83,7 @@ shared_examples_for 'group and project milestones' do |route_definition| end it 'returns a milestones by searching for description' do - get api(route, user), search: 'open' + get api(route, user), params: { search: 'open' } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers @@ -117,7 +117,7 @@ shared_examples_for 'group and project milestones' do |route_definition| describe "POST #{route_definition}" do it 'creates a new milestone' do - post api(route, user), title: 'new milestone' + post api(route, user), params: { title: 'new milestone' } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('new milestone') @@ -125,8 +125,7 @@ shared_examples_for 'group and project milestones' do |route_definition| end it 'creates a new milestone with description and dates' do - post api(route, user), - title: 'new milestone', description: 'release', due_date: '2013-03-02', start_date: '2013-02-02' + post api(route, user), params: { title: 'new milestone', description: 'release', due_date: '2013-03-02', start_date: '2013-02-02' } expect(response).to have_gitlab_http_status(201) expect(json_response['description']).to eq('release') @@ -141,14 +140,13 @@ shared_examples_for 'group and project milestones' do |route_definition| end it 'returns a 400 error if params are invalid (duplicate title)' do - post api(route, user), - title: milestone.title, description: 'release', due_date: '2013-03-02' + post api(route, user), params: { title: milestone.title, description: 'release', due_date: '2013-03-02' } expect(response).to have_gitlab_http_status(400) end it 'creates a new milestone with reserved html characters' do - post api(route, user), title: 'foo & bar 1.1 -> 2.2' + post api(route, user), params: { title: 'foo & bar 1.1 -> 2.2' } expect(response).to have_gitlab_http_status(201) expect(json_response['title']).to eq('foo & bar 1.1 -> 2.2') @@ -158,8 +156,7 @@ shared_examples_for 'group and project milestones' do |route_definition| describe "PUT #{route_definition}/:milestone_id" do it 'updates a milestone' do - put api(resource_route, user), - title: 'updated title' + put api(resource_route, user), params: { title: 'updated title' } expect(response).to have_gitlab_http_status(200) expect(json_response['title']).to eq('updated title') @@ -168,29 +165,27 @@ shared_examples_for 'group and project milestones' do |route_definition| it 'removes a due date if nil is passed' do milestone.update!(due_date: "2016-08-05") - put api(resource_route, user), due_date: nil + put api(resource_route, user), params: { due_date: nil } expect(response).to have_gitlab_http_status(200) expect(json_response['due_date']).to be_nil end it 'returns a 404 error if milestone id not found' do - put api("#{route}/1234", user), - title: 'updated title' + put api("#{route}/1234", user), params: { title: 'updated title' } expect(response).to have_gitlab_http_status(404) end it 'closes milestone' do - put api(resource_route, user), - state_event: 'close' + put api(resource_route, user), params: { state_event: 'close' } expect(response).to have_gitlab_http_status(200) expect(json_response['state']).to eq('closed') end it 'updates milestone with only start date' do - put api(resource_route, user), start_date: Date.tomorrow + put api(resource_route, user), params: { start_date: Date.tomorrow } expect(response).to have_gitlab_http_status(200) end diff --git a/spec/support/api/scopes/read_user_shared_examples.rb b/spec/support/api/scopes/read_user_shared_examples.rb index d7cef137989..683234264a8 100644 --- a/spec/support/api/scopes/read_user_shared_examples.rb +++ b/spec/support/api/scopes/read_user_shared_examples.rb @@ -77,7 +77,7 @@ shared_examples_for 'does not allow the "read_user" scope' do let(:token) { create(:personal_access_token, scopes: ['read_user'], user: user) } it 'returns a "403" response' do - post api_call.call(path, user, personal_access_token: token), attributes_for(:user, projects_limit: 3) + post api_call.call(path, user, personal_access_token: token), params: attributes_for(:user, projects_limit: 3) expect(response).to have_gitlab_http_status(403) end diff --git a/spec/support/api/time_tracking_shared_examples.rb b/spec/support/api/time_tracking_shared_examples.rb index fee464c15a3..e883d33f671 100644 --- a/spec/support/api/time_tracking_shared_examples.rb +++ b/spec/support/api/time_tracking_shared_examples.rb @@ -7,13 +7,13 @@ shared_examples 'time tracking endpoints' do |issuable_name| describe "POST /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/time_estimate" do context 'with an unauthorized user' do - subject { post(api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", non_member), duration: '1w') } + subject { post(api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", non_member), params: { duration: '1w' }) } it_behaves_like 'an unauthorized API user' end it "sets the time estimate for #{issuable_name}" do - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: '1w' + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: '1w' } expect(response).to have_gitlab_http_status(200) expect(json_response['human_time_estimate']).to eq('1w') @@ -21,12 +21,12 @@ shared_examples 'time tracking endpoints' do |issuable_name| describe 'updating the current estimate' do before do - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: '1w' + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: '1w' } end context 'when duration has a bad format' do it 'does not modify the original estimate' do - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: 'foo' + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: 'foo' } expect(response).to have_gitlab_http_status(400) expect(issuable.reload.human_time_estimate).to eq('1w') @@ -35,7 +35,7 @@ shared_examples 'time tracking endpoints' do |issuable_name| context 'with a valid duration' do it 'updates the estimate' do - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: '3w1h' + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: '3w1h' } expect(response).to have_gitlab_http_status(200) expect(issuable.reload.human_time_estimate).to eq('3w 1h') @@ -62,8 +62,7 @@ shared_examples 'time tracking endpoints' do |issuable_name| describe "POST /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/add_spent_time" do context 'with an unauthorized user' do subject do - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", non_member), - duration: '2h' + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", non_member), params: { duration: '2h' } end it_behaves_like 'an unauthorized API user' @@ -72,8 +71,7 @@ shared_examples 'time tracking endpoints' do |issuable_name| it "add spent time for #{issuable_name}" do Timecop.travel(1.minute.from_now) do expect do - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), - duration: '2h' + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '2h' } end.to change { issuable.reload.updated_at } end @@ -89,8 +87,7 @@ shared_examples 'time tracking endpoints' do |issuable_name| end.to change { issuable.reload.updated_at } end - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), - duration: '-1h' + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '-1h' } expect(response).to have_gitlab_http_status(201) expect(json_response['total_time_spent']).to eq(3600) @@ -103,8 +100,7 @@ shared_examples 'time tracking endpoints' do |issuable_name| Timecop.travel(1.minute.from_now) do expect do - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), - duration: '-1w' + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '-1w' } end.not_to change { issuable.reload.updated_at } end diff --git a/spec/support/carrierwave.rb b/spec/support/carrierwave.rb index b4b016e408f..b376822d530 100644 --- a/spec/support/carrierwave.rb +++ b/spec/support/carrierwave.rb @@ -1,7 +1,7 @@ CarrierWave.root = File.expand_path('tmp/tests/public', Rails.root) RSpec.configure do |config| - config.after(:each) do + config.after do FileUtils.rm_rf(CarrierWave.root) end end diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb index 140490f2dc2..697f999e4c4 100644 --- a/spec/support/controllers/githubish_import_controller_shared_examples.rb +++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb @@ -17,7 +17,7 @@ shared_examples 'a GitHub-ish import controller: POST personal_access_token' do allow_any_instance_of(Gitlab::LegacyGithubImport::Client) .to receive(:user).and_return(true) - post :personal_access_token, personal_access_token: token + post :personal_access_token, params: { personal_access_token: token } expect(session[:"#{provider}_access_token"]).to eq(token) expect(controller).to redirect_to(status_import_url) @@ -29,7 +29,7 @@ shared_examples 'a GitHub-ish import controller: POST personal_access_token' do allow_any_instance_of(Gitlab::LegacyGithubImport::Client) .to receive(:user).and_return(true) - post :personal_access_token, personal_access_token: " #{token} " + post :personal_access_token, params: { personal_access_token: " #{token} " } expect(session[:"#{provider}_access_token"]).to eq(token) expect(controller).to redirect_to(status_import_url) @@ -214,7 +214,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do expect(Gitlab::LegacyGithubImport::ProjectCreator) .to receive(:new).and_return(double(execute: project)) - expect { post :create, target_namespace: provider_repo.name, format: :json }.to change(Namespace, :count).by(1) + expect { post :create, params: { target_namespace: provider_repo.name }, format: :json }.to change(Namespace, :count).by(1) end it "takes the new namespace" do @@ -222,7 +222,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider) .and_return(double(execute: project)) - post :create, target_namespace: provider_repo.name, format: :json + post :create, params: { target_namespace: provider_repo.name }, format: :json end end @@ -261,7 +261,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider) .and_return(double(execute: project)) - post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :json } + post :create, params: { target_namespace: test_namespace.name, new_name: test_name }, format: :json end it 'takes the selected name and default namespace' do @@ -269,7 +269,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider) .and_return(double(execute: project)) - post :create, { new_name: test_name, format: :json } + post :create, params: { new_name: test_name }, format: :json end end @@ -288,7 +288,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, nested_namespace, user, access_params, type: provider) .and_return(double(execute: project)) - post :create, { target_namespace: nested_namespace.full_path, new_name: test_name, format: :json } + post :create, params: { target_namespace: nested_namespace.full_path, new_name: test_name }, format: :json end end @@ -300,7 +300,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider) .and_return(double(execute: project)) - post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json } + post :create, params: { target_namespace: 'foo/bar', new_name: test_name }, format: :json end it 'creates the namespaces' do @@ -308,7 +308,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider) .and_return(double(execute: project)) - expect { post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json } } + expect { post :create, params: { target_namespace: 'foo/bar', new_name: test_name }, format: :json } .to change { Namespace.count }.by(2) end @@ -317,7 +317,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider) .and_return(double(execute: project)) - post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json } + post :create, params: { target_namespace: 'foo/bar', new_name: test_name }, format: :json expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo') end @@ -336,7 +336,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider) .and_return(double(execute: project)) - post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :json } + post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :json end it 'creates the namespaces' do @@ -344,7 +344,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider) .and_return(double(execute: project)) - expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :json } } + expect { post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :json } .to change { Namespace.count }.by(2) end @@ -353,7 +353,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider) .and_return(double(execute: build_stubbed(:project))) - expect { post :create, { target_namespace: "#{user.namespace_path}/test_group", new_name: test_name, format: :js } } + expect { post :create, params: { target_namespace: "#{user.namespace_path}/test_group", new_name: test_name }, format: :js } .not_to change { Namespace.count } end end @@ -367,7 +367,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider) .and_return(double(execute: build_stubbed(:project))) - post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js } + post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :js end it 'does not create the namespaces' do @@ -375,7 +375,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider) .and_return(double(execute: build_stubbed(:project))) - expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js } } + expect { post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :js } .not_to change { Namespace.count } end end @@ -392,7 +392,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do .to receive(:new).with(provider_repo, test_name, group, user, access_params, type: provider) .and_return(double(execute: build_stubbed(:project))) - post :create, { target_namespace: 'foo', new_name: test_name, format: :js } + post :create, params: { target_namespace: 'foo', new_name: test_name }, format: :js end end @@ -400,7 +400,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do it 'returns 422 response' do other_namespace = create(:group, name: 'other_namespace') - post :create, { target_namespace: other_namespace.name, format: :json } + post :create, params: { target_namespace: other_namespace.name }, format: :json expect(response).to have_gitlab_http_status(422) end diff --git a/spec/support/controllers/sessionless_auth_controller_shared_examples.rb b/spec/support/controllers/sessionless_auth_controller_shared_examples.rb index 7e4958f177a..355555d9d19 100644 --- a/spec/support/controllers/sessionless_auth_controller_shared_examples.rb +++ b/spec/support/controllers/sessionless_auth_controller_shared_examples.rb @@ -16,14 +16,14 @@ shared_examples 'authenticates sessionless user' do |path, format, params| .and increment(:user_session_override_counter) .and increment(:user_sessionless_authentication_counter) - get path, default_params.merge(private_token: personal_access_token.token) + get path, params: default_params.merge(private_token: personal_access_token.token) expect(response).to have_gitlab_http_status(200) expect(controller.current_user).to eq(user) end it 'does not log the user in if page is public', if: params[:public] do - get path, default_params + get path, params: default_params expect(response).to have_gitlab_http_status(200) expect(controller.current_user).to be_nil @@ -37,7 +37,7 @@ shared_examples 'authenticates sessionless user' do |path, format, params| personal_access_token.update(scopes: [:read_user]) - get path, default_params.merge(private_token: personal_access_token.token) + get path, params: default_params.merge(private_token: personal_access_token.token) expect(response).not_to have_gitlab_http_status(200) end @@ -51,7 +51,7 @@ shared_examples 'authenticates sessionless user' do |path, format, params| .and increment(:user_sessionless_authentication_counter) @request.headers['PRIVATE-TOKEN'] = personal_access_token.token - get path, default_params + get path, params: default_params expect(response).to have_gitlab_http_status(200) end @@ -64,7 +64,7 @@ shared_examples 'authenticates sessionless user' do |path, format, params| .and increment(:user_session_override_counter) .and increment(:user_sessionless_authentication_counter) - get path, default_params.merge(feed_token: user.feed_token) + get path, params: default_params.merge(feed_token: user.feed_token) expect(response).to have_gitlab_http_status 200 end @@ -75,7 +75,7 @@ shared_examples 'authenticates sessionless user' do |path, format, params| expect(authentication_metrics) .to increment(:user_unauthenticated_counter) - get path, default_params.merge(feed_token: 'token') + get path, params: default_params.merge(feed_token: 'token') expect(response.status).not_to eq 200 end @@ -85,7 +85,7 @@ shared_examples 'authenticates sessionless user' do |path, format, params| expect(authentication_metrics) .to increment(:user_unauthenticated_counter) - get path, default_params.merge(private_token: 'token') + get path, params: default_params.merge(private_token: 'token') expect(response.status).not_to eq(200) end diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb index 5edc5de2a09..34b9efaaecd 100644 --- a/spec/support/db_cleaner.rb +++ b/spec/support/db_cleaner.rb @@ -23,7 +23,7 @@ RSpec.configure do |config| DatabaseCleaner.clean_with(:deletion, cache_tables: false) end - config.before(:each) do + config.before do DatabaseCleaner.strategy = :transaction end @@ -39,11 +39,11 @@ RSpec.configure do |config| DatabaseCleaner.strategy = :deletion, { cache_tables: false } end - config.before(:each) do + config.before do DatabaseCleaner.start end - config.append_after(:each) do + config.append_after do DatabaseCleaner.clean end end diff --git a/spec/support/features/discussion_comments_shared_example.rb b/spec/support/features/discussion_comments_shared_example.rb index 922f3df144d..42a086d58d2 100644 --- a/spec/support/features/discussion_comments_shared_example.rb +++ b/spec/support/features/discussion_comments_shared_example.rb @@ -178,6 +178,16 @@ shared_examples 'discussion comments' do |resource_name| let(:note_id) { find("#{comments_selector} .note:first-child", match: :first)['data-note-id'] } let(:reply_id) { find("#{comments_selector} .note:last-child", match: :first)['data-note-id'] } + it 'can be replied to after resolving' do + click_button "Resolve discussion" + wait_for_requests + + refresh + wait_for_requests + + submit_reply('to reply or not reply') + end + it 'shows resolved discussion when toggled' do submit_reply('a') diff --git a/spec/support/features/variable_list_shared_examples.rb b/spec/support/features/variable_list_shared_examples.rb index bce1fb01355..0a464d77cb7 100644 --- a/spec/support/features/variable_list_shared_examples.rb +++ b/spec/support/features/variable_list_shared_examples.rb @@ -63,6 +63,52 @@ shared_examples 'variable list' do end end + context 'defaults to the application setting' do + context 'application setting is true' do + before do + stub_application_setting(protected_ci_variables: true) + + visit page_path + end + + it 'defaults to protected' do + page.within('.js-ci-variable-list-section .js-row:last-child') do + find('.js-ci-variable-input-key').set('key') + end + + values = all('.js-ci-variable-input-protected', visible: false).map(&:value) + + expect(values).to eq %w(false true true) + end + + it 'shows a message regarding the changed default' do + expect(page).to have_content 'Environment variables are configured by your administrator to be protected by default' + end + end + + context 'application setting is false' do + before do + stub_application_setting(protected_ci_variables: false) + + visit page_path + end + + it 'defaults to unprotected' do + page.within('.js-ci-variable-list-section .js-row:last-child') do + find('.js-ci-variable-input-key').set('key') + end + + values = all('.js-ci-variable-input-protected', visible: false).map(&:value) + + expect(values).to eq %w(false false false) + end + + it 'does not show a message regarding the default' do + expect(page).not_to have_content 'Environment variables are configured by your administrator to be protected by default' + end + end + end + it 'reveals and hides variables' do page.within('.js-ci-variable-list-section') do expect(first('.js-ci-variable-input-key').value).to eq(variable.key) diff --git a/spec/support/gitlab_stubs/gitlab_ci.yml b/spec/support/gitlab_stubs/gitlab_ci.yml index e55a61b2b94..f3755e52b2c 100644 --- a/spec/support/gitlab_stubs/gitlab_ci.yml +++ b/spec/support/gitlab_stubs/gitlab_ci.yml @@ -1,9 +1,8 @@ -image: ruby:2.1 +image: ruby:2.6 services: - postgres before_script: - - gem install bundler - bundle install - bundle exec rake db:create diff --git a/spec/support/helpers/email_helpers.rb b/spec/support/helpers/email_helpers.rb index 1fb8252459f..ad6e1064499 100644 --- a/spec/support/helpers/email_helpers.rb +++ b/spec/support/helpers/email_helpers.rb @@ -34,4 +34,13 @@ module EmailHelpers def find_email_for(user) ActionMailer::Base.deliveries.find { |d| d.to.include?(user.notification_email) } end + + def have_referable_subject(referable, include_project: true, reply: false) + prefix = (include_project && referable.project ? "#{referable.project.name} | " : '').freeze + prefix = "Re: #{prefix}" if reply + + suffix = "#{referable.title} (#{referable.to_reference})" + + have_subject [prefix, suffix].compact.join + end end diff --git a/spec/support/helpers/fake_blob_helpers.rb b/spec/support/helpers/fake_blob_helpers.rb index bc9686ed9cf..801ca8b7412 100644 --- a/spec/support/helpers/fake_blob_helpers.rb +++ b/spec/support/helpers/fake_blob_helpers.rb @@ -23,7 +23,7 @@ module FakeBlobHelpers 0 end - def binary? + def binary_in_repo? @binary end diff --git a/spec/support/helpers/fake_migration_classes.rb b/spec/support/helpers/fake_migration_classes.rb index b0fc8422857..c7766df7a52 100644 --- a/spec/support/helpers/fake_migration_classes.rb +++ b/spec/support/helpers/fake_migration_classes.rb @@ -1,4 +1,4 @@ -class FakeRenameReservedPathMigrationV1 < ActiveRecord::Migration +class FakeRenameReservedPathMigrationV1 < ActiveRecord::Migration[4.2] include Gitlab::Database::RenameReservedPathsMigration::V1 def version diff --git a/spec/support/helpers/git_http_helpers.rb b/spec/support/helpers/git_http_helpers.rb index 9a5845af90c..cd49bb148f2 100644 --- a/spec/support/helpers/git_http_helpers.rb +++ b/spec/support/helpers/git_http_helpers.rb @@ -1,18 +1,18 @@ module GitHttpHelpers def clone_get(project, options = {}) - get "/#{project}/info/refs", { service: 'git-upload-pack' }, auth_env(*options.values_at(:user, :password, :spnego_request_token)) + get "/#{project}/info/refs", params: { service: 'git-upload-pack' }, headers: auth_env(*options.values_at(:user, :password, :spnego_request_token)) end def clone_post(project, options = {}) - post "/#{project}/git-upload-pack", {}, auth_env(*options.values_at(:user, :password, :spnego_request_token)) + post "/#{project}/git-upload-pack", headers: auth_env(*options.values_at(:user, :password, :spnego_request_token)) end def push_get(project, options = {}) - get "/#{project}/info/refs", { service: 'git-receive-pack' }, auth_env(*options.values_at(:user, :password, :spnego_request_token)) + get "/#{project}/info/refs", params: { service: 'git-receive-pack' }, headers: auth_env(*options.values_at(:user, :password, :spnego_request_token)) end def push_post(project, options = {}) - post "/#{project}/git-receive-pack", {}, auth_env(*options.values_at(:user, :password, :spnego_request_token)) + post "/#{project}/git-receive-pack", headers: auth_env(*options.values_at(:user, :password, :spnego_request_token)) end def download(project, user: nil, password: nil, spnego_request_token: nil) diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb index 75827df80dc..dd32ea3985f 100644 --- a/spec/support/helpers/graphql_helpers.rb +++ b/spec/support/helpers/graphql_helpers.rb @@ -107,7 +107,7 @@ module GraphqlHelpers end def post_graphql(query, current_user: nil, variables: nil) - post api('/', current_user, version: 'graphql'), query: query, variables: variables + post api('/', current_user, version: 'graphql'), params: { query: query, variables: variables } end def post_graphql_mutation(mutation, current_user: nil) diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb index 39bd305d88a..e7d97561bfc 100644 --- a/spec/support/helpers/kubernetes_helpers.rb +++ b/spec/support/helpers/kubernetes_helpers.rb @@ -58,6 +58,11 @@ module KubernetesHelpers .to_return(status: [status, "Internal Server Error"]) end + def stub_kubeclient_get_service_account(api_url, name, namespace: 'default') + WebMock.stub_request(:get, api_url + "/api/v1/namespaces/#{namespace}/serviceaccounts/#{name}") + .to_return(kube_response({})) + end + def stub_kubeclient_get_service_account_error(api_url, name, namespace: 'default', status: 404) WebMock.stub_request(:get, api_url + "/api/v1/namespaces/#{namespace}/serviceaccounts/#{name}") .to_return(status: [status, "Internal Server Error"]) @@ -73,6 +78,11 @@ module KubernetesHelpers .to_return(status: [500, "Internal Server Error"]) end + def stub_kubeclient_put_service_account(api_url, name, namespace: 'default') + WebMock.stub_request(:put, api_url + "/api/v1/namespaces/#{namespace}/serviceaccounts/#{name}") + .to_return(kube_response({})) + end + def stub_kubeclient_create_secret(api_url, namespace: 'default') WebMock.stub_request(:post, api_url + "/api/v1/namespaces/#{namespace}/secrets") .to_return(kube_response({})) @@ -93,6 +103,11 @@ module KubernetesHelpers .to_return(kube_response({})) end + def stub_kubeclient_get_role_binding(api_url, name, namespace: 'default') + WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}") + .to_return(kube_response({})) + end + def stub_kubeclient_get_role_binding_error(api_url, name, namespace: 'default', status: 404) WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}") .to_return(status: [status, "Internal Server Error"]) @@ -103,6 +118,11 @@ module KubernetesHelpers .to_return(kube_response({})) end + def stub_kubeclient_put_role_binding(api_url, name, namespace: 'default') + WebMock.stub_request(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}") + .to_return(kube_response({})) + end + def stub_kubeclient_create_namespace(api_url) WebMock.stub_request(:post, api_url + "/api/v1/namespaces") .to_return(kube_response({})) diff --git a/spec/support/helpers/migrations_helpers.rb b/spec/support/helpers/migrations_helpers.rb index 5887c3eab74..cc1a28cb264 100644 --- a/spec/support/helpers/migrations_helpers.rb +++ b/spec/support/helpers/migrations_helpers.rb @@ -62,6 +62,22 @@ module MigrationsHelpers klass.reset_column_information end + # In some migration tests, we're using factories to create records, + # however those models might be depending on a schema version which + # doesn't have the columns we want in application_settings. + # In these cases, we'll need to use the fake application settings + # as if we have migrations pending + def use_fake_application_settings + # We stub this way because we can't stub on + # `current_application_settings` due to `method_missing` is + # depending on current_application_settings... + allow(ActiveRecord::Base.connection) + .to receive(:active?) + .and_return(false) + + stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') + end + def previous_migration migrations.each_cons(2) do |previous, migration| break previous if migration.name == described_class.name diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb index d52c40ff4f1..d352a7cdf1a 100644 --- a/spec/support/helpers/test_env.rb +++ b/spec/support/helpers/test_env.rb @@ -62,7 +62,8 @@ module TestEnv 'between-create-delete-modify-move' => '3f5f443', 'after-create-delete-modify-move' => 'ba3faa7', 'with-codeowners' => '219560e', - 'submodule_inside_folder' => 'b491b92' + 'submodule_inside_folder' => 'b491b92', + 'png-lfs' => 'fe42f41' }.freeze # gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily diff --git a/spec/support/helpers/test_request_helpers.rb b/spec/support/helpers/test_request_helpers.rb index 187a0e07891..5a84d67bdfc 100644 --- a/spec/support/helpers/test_request_helpers.rb +++ b/spec/support/helpers/test_request_helpers.rb @@ -2,10 +2,6 @@ module TestRequestHelpers def test_request(remote_ip: '127.0.0.1') - if Gitlab.rails5? - ActionController::TestRequest.new({ remote_ip: remote_ip }, ActionController::TestSession.new) - else - ActionController::TestRequest.new(remote_ip: remote_ip) - end + ActionController::TestRequest.new({ remote_ip: remote_ip }, ActionController::TestSession.new) end end diff --git a/spec/support/import_export/export_file_helper.rb b/spec/support/import_export/export_file_helper.rb index a49036c3b80..ac320934f5a 100644 --- a/spec/support/import_export/export_file_helper.rb +++ b/spec/support/import_export/export_file_helper.rb @@ -133,6 +133,6 @@ module ExportFileHelper end def file_permissions(file) - File.stat(file).mode & 0777 + File.lstat(file).mode & 0777 end end diff --git a/spec/support/issuables_requiring_filter_shared_examples.rb b/spec/support/issuables_requiring_filter_shared_examples.rb index 439ef5ed92e..71bcc82ee58 100644 --- a/spec/support/issuables_requiring_filter_shared_examples.rb +++ b/spec/support/issuables_requiring_filter_shared_examples.rb @@ -10,6 +10,6 @@ shared_examples 'issuables requiring filter' do |action| it "loads issuables if at least one filter is set" do expect_any_instance_of(described_class).to receive(:issuables_collection).and_call_original - get action, author_id: user.id + get action, params: { author_id: user.id } end end diff --git a/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb b/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb index 1478c6b5a47..62ae95df8c0 100644 --- a/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb +++ b/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb @@ -86,7 +86,7 @@ shared_examples "migrating a deleted user's associated records to the ghost user end it "blocks the user before #{record_class_name} migration begins" do - expect(service).to receive("migrate_#{record_class_name.parameterize('_').pluralize}".to_sym) do + expect(service).to receive("migrate_#{record_class_name.parameterize(separator: '_').pluralize}".to_sym) do expect(user.reload).to be_blocked end diff --git a/spec/support/setup_builds_storage.rb b/spec/support/setup_builds_storage.rb index 2e7c88bfc09..1d2a4856724 100644 --- a/spec/support/setup_builds_storage.rb +++ b/spec/support/setup_builds_storage.rb @@ -11,7 +11,7 @@ RSpec.configure do |config| FileUtils.mkdir_p(builds_path) end - config.before(:each) do + config.before do FileUtils.rm_rf(builds_path) FileUtils.mkdir_p(builds_path) end diff --git a/spec/support/shared_examples/common_system_notes_examples.rb b/spec/support/shared_examples/common_system_notes_examples.rb index 96ef30b7513..da5a4f3e319 100644 --- a/spec/support/shared_examples/common_system_notes_examples.rb +++ b/spec/support/shared_examples/common_system_notes_examples.rb @@ -1,5 +1,5 @@ shared_examples 'system note creation' do |update_params, note_text| - subject { described_class.new(project, user).execute(issuable, [])} + subject { described_class.new(project, user).execute(issuable, old_labels: []) } before do issuable.assign_attributes(update_params) @@ -16,7 +16,7 @@ shared_examples 'system note creation' do |update_params, note_text| end shared_examples 'WIP notes creation' do |wip_action| - subject { described_class.new(project, user).execute(issuable, []) } + subject { described_class.new(project, user).execute(issuable, old_labels: []) } it 'creates WIP toggle and title change notes' do expect { subject }.to change { Note.count }.from(0).to(2) diff --git a/spec/support/shared_examples/controllers/issuable_notes_filter_shared_examples.rb b/spec/support/shared_examples/controllers/issuable_notes_filter_shared_examples.rb index 95e69328080..dbdca99b5aa 100644 --- a/spec/support/shared_examples/controllers/issuable_notes_filter_shared_examples.rb +++ b/spec/support/shared_examples/controllers/issuable_notes_filter_shared_examples.rb @@ -2,7 +2,7 @@ shared_examples 'issuable notes filter' do it 'sets discussion filter' do notes_filter = UserPreference::NOTES_FILTERS[:only_comments] - get :discussions, namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter } expect(user.reload.notes_filter_for(issuable)).to eq(notes_filter) expect(UserPreference.count).to eq(1) @@ -13,7 +13,7 @@ shared_examples 'issuable notes filter' do expect_any_instance_of(issuable.class).to receive(:expire_note_etag_cache) - get :discussions, namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter } end it 'does not expires notes e-tag cache for issuable if filter did not change' do @@ -22,14 +22,14 @@ shared_examples 'issuable notes filter' do expect_any_instance_of(issuable.class).not_to receive(:expire_note_etag_cache) - get :discussions, namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter } end it 'does not set notes filter when database is in read only mode' do allow(Gitlab::Database).to receive(:read_only?).and_return(true) notes_filter = UserPreference::NOTES_FILTERS[:only_comments] - get :discussions, namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter } expect(user.reload.notes_filter_for(issuable)).to eq(0) end @@ -37,7 +37,7 @@ shared_examples 'issuable notes filter' do it 'returns only user comments' do user.set_notes_filter(UserPreference::NOTES_FILTERS[:only_comments], issuable) - get :discussions, namespace_id: project.namespace, project_id: project, id: issuable.iid + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid } discussions = JSON.parse(response.body) expect(discussions.count).to eq(1) @@ -47,7 +47,7 @@ shared_examples 'issuable notes filter' do it 'returns only activity notes' do user.set_notes_filter(UserPreference::NOTES_FILTERS[:only_activity], issuable) - get :discussions, namespace_id: project.namespace, project_id: project, id: issuable.iid + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid } discussions = JSON.parse(response.body) expect(discussions.count).to eq(1) @@ -60,7 +60,7 @@ shared_examples 'issuable notes filter' do expect(ResourceEvents::MergeIntoNotesService).not_to receive(:new) - get :discussions, namespace_id: project.namespace, project_id: project, id: issuable.iid + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid } end end end diff --git a/spec/support/shared_examples/controllers/set_sort_order_from_user_preference_shared_examples.rb b/spec/support/shared_examples/controllers/set_sort_order_from_user_preference_shared_examples.rb new file mode 100644 index 00000000000..d86838719d4 --- /dev/null +++ b/spec/support/shared_examples/controllers/set_sort_order_from_user_preference_shared_examples.rb @@ -0,0 +1,32 @@ +shared_examples 'set sort order from user preference' do + describe '#set_sort_order_from_user_preference' do + # There is no issuable_sorting_field defined in any CE controllers yet, + # however any other field present in user_preferences table can be used for testing. + let(:sorting_field) { :issue_notes_filter } + let(:sorting_param) { 'any' } + + before do + allow(controller).to receive(:issuable_sorting_field).and_return(sorting_field) + end + + context 'when database is in read-only mode' do + it 'it does not update user preference' do + allow(Gitlab::Database).to receive(:read_only?).and_return(true) + + expect_any_instance_of(UserPreference).not_to receive(:update_attribute).with(sorting_field, sorting_param) + + get :index, params: { namespace_id: project.namespace, project_id: project, sort: sorting_param } + end + end + + context 'when database is not in read-only mode' do + it 'updates user preference' do + allow(Gitlab::Database).to receive(:read_only?).and_return(false) + + expect_any_instance_of(UserPreference).to receive(:update_attribute).with(sorting_field, sorting_param) + + get :index, params: { namespace_id: project.namespace, project_id: project, sort: sorting_param } + end + end + end +end diff --git a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb index 7088fb1e5fb..59708173716 100644 --- a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb +++ b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb @@ -8,8 +8,7 @@ shared_examples 'handle uploads' do describe "POST #create" do context 'when a user is not authorized to upload a file' do it 'returns 404 status' do - post :create, params.merge(file: jpg, format: :json) - + post :create, params: params.merge(file: jpg), format: :json expect(response.status).to eq(404) end end @@ -22,7 +21,7 @@ shared_examples 'handle uploads' do context "without params['file']" do it "returns an error" do - post :create, params.merge(format: :json) + post :create, params: params, format: :json expect(response).to have_gitlab_http_status(422) end @@ -30,7 +29,7 @@ shared_examples 'handle uploads' do context 'with valid image' do before do - post :create, params.merge(file: jpg, format: :json) + post :create, params: params.merge(file: jpg), format: :json end it 'returns a content with original filename, new link, and correct type.' do @@ -54,7 +53,7 @@ shared_examples 'handle uploads' do context 'with valid non-image file' do before do - post :create, params.merge(file: txt, format: :json) + post :create, params: params.merge(file: txt), format: :json end it 'returns a content with original filename, new link, and correct type.' do @@ -67,7 +66,7 @@ shared_examples 'handle uploads' do describe "GET #show" do let(:show_upload) do - get :show, params.merge(secret: secret, filename: "rails_sample.jpg") + get :show, params: params.merge(secret: secret, filename: "rails_sample.jpg") end before do diff --git a/spec/support/shared_examples/issuables_list_metadata_shared_examples.rb b/spec/support/shared_examples/issuables_list_metadata_shared_examples.rb index f4bc6f8efa5..90d67fd00fc 100644 --- a/spec/support/shared_examples/issuables_list_metadata_shared_examples.rb +++ b/spec/support/shared_examples/issuables_list_metadata_shared_examples.rb @@ -3,9 +3,9 @@ shared_examples 'issuables list meta-data' do |issuable_type, action = nil| def get_action(action, project) if action - get action, author_id: project.creator.id + get action, params: { author_id: project.creator.id } else - get :index, namespace_id: project.namespace, project_id: project + get :index, params: { namespace_id: project.namespace, project_id: project } end end @@ -51,9 +51,9 @@ shared_examples 'issuables list meta-data' do |issuable_type, action = nil| it "doesn't execute any queries with false conditions" do get_empty = if action - proc { get action, author_id: project.creator.id } + proc { get action, params: { author_id: project.creator.id } } else - proc { get :index, namespace_id: project2.namespace, project_id: project2 } + proc { get :index, params: { namespace_id: project2.namespace, project_id: project2 } } end expect(&get_empty).not_to make_queries_matching(/WHERE (?:1=0|0=1)/) diff --git a/spec/support/shared_examples/lib/gitlab/background_migration/backfill_project_repositories_examples.rb b/spec/support/shared_examples/lib/gitlab/background_migration/backfill_project_repositories_examples.rb new file mode 100644 index 00000000000..1f688c0f9d3 --- /dev/null +++ b/spec/support/shared_examples/lib/gitlab/background_migration/backfill_project_repositories_examples.rb @@ -0,0 +1,44 @@ +shared_examples 'backfill migration for project repositories' do |storage| + describe '#perform' do + let(:storage_versions) { storage == :legacy ? [nil, 0] : [1, 2] } + let(:storage_version) { storage_versions.first } + let(:namespaces) { table(:namespaces) } + let(:project_repositories) { table(:project_repositories) } + let(:projects) { table(:projects) } + let(:shards) { table(:shards) } + let(:group) { namespaces.create!(name: 'foo', path: 'foo') } + let(:shard) { shards.create!(name: 'default') } + + it "creates a project_repository row for projects on #{storage} storage that needs one" do + storage_versions.each_with_index do |storage_version, index| + projects.create!(name: "foo-#{index}", path: "foo-#{index}", namespace_id: group.id, storage_version: storage_version) + end + + expect { described_class.new.perform(1, projects.last.id) }.to change(project_repositories, :count).by(2) + end + + it "does nothing for projects on #{storage} storage that have already a project_repository row" do + projects.create!(id: 1, name: 'foo', path: 'foo', namespace_id: group.id, storage_version: storage_version) + project_repositories.create!(project_id: 1, disk_path: 'phony/foo/bar', shard_id: shard.id) + + expect { described_class.new.perform(1, projects.last.id) }.not_to change(project_repositories, :count) + end + + it "does nothing for projects on #{storage == :legacy ? 'hashed' : 'legacy'} storage" do + projects.create!(name: 'foo', path: 'foo', namespace_id: group.id, storage_version: storage == :legacy ? 1 : nil) + + expect { described_class.new.perform(1, projects.last.id) }.not_to change(project_repositories, :count) + end + + it 'inserts rows in a single query' do + projects.create!(name: 'foo', path: 'foo', namespace_id: group.id, storage_version: storage_version, repository_storage: shard.name) + + control_count = ActiveRecord::QueryRecorder.new { described_class.new.perform(1, projects.last.id) } + + projects.create!(name: 'bar', path: 'bar', namespace_id: group.id, storage_version: storage_version, repository_storage: shard.name) + projects.create!(name: 'zoo', path: 'zoo', namespace_id: group.id, storage_version: storage_version, repository_storage: shard.name) + + expect { described_class.new.perform(1, projects.last.id) }.not_to exceed_query_limit(control_count) + end + end +end diff --git a/spec/support/shared_examples/milestone_tabs_examples.rb b/spec/support/shared_examples/milestone_tabs_examples.rb index 70b499198bf..8b757586941 100644 --- a/spec/support/shared_examples/milestone_tabs_examples.rb +++ b/spec/support/shared_examples/milestone_tabs_examples.rb @@ -10,7 +10,7 @@ shared_examples 'milestone tabs' do { namespace_id: project.namespace.to_param, project_id: project, id: milestone.iid } end - get path, params.merge(extra_params) + get path, params: params.merge(extra_params) end describe '#merge_requests' do diff --git a/spec/support/shared_examples/notify_shared_examples.rb b/spec/support/shared_examples/notify_shared_examples.rb index 66536e80db2..a38354060cf 100644 --- a/spec/support/shared_examples/notify_shared_examples.rb +++ b/spec/support/shared_examples/notify_shared_examples.rb @@ -1,5 +1,5 @@ shared_context 'gitlab email notification' do - set(:project) { create(:project, :repository) } + set(:project) { create(:project, :repository, name: 'a-known-name') } set(:recipient) { create(:user, email: 'recipient@example.com') } let(:gitlab_sender_display_name) { Gitlab.config.gitlab.email_display_name } @@ -62,9 +62,11 @@ end shared_examples 'an email with X-GitLab headers containing project details' do it 'has X-GitLab-Project headers' do aggregate_failures do + full_path_as_domain = "#{project.name}.#{project.namespace.path}" is_expected.to have_header('X-GitLab-Project', /#{project.name}/) is_expected.to have_header('X-GitLab-Project-Id', /#{project.id}/) is_expected.to have_header('X-GitLab-Project-Path', /#{project.full_path}/) + is_expected.to have_header('List-Id', "#{project.full_path} <#{project.id}.#{full_path_as_domain}.#{Gitlab.config.gitlab.host}>") end end end diff --git a/spec/support/shared_examples/only_except_policy_examples.rb b/spec/support/shared_examples/only_except_policy_examples.rb deleted file mode 100644 index 35240af1d74..00000000000 --- a/spec/support/shared_examples/only_except_policy_examples.rb +++ /dev/null @@ -1,167 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'correct only except policy' do - context 'when using simplified policy' do - describe 'validations' do - context 'when entry config value is valid' do - context 'when config is a branch or tag name' do - let(:config) { %w[master feature/branch] } - - describe '#valid?' do - it 'is valid' do - expect(entry).to be_valid - end - end - - describe '#value' do - it 'returns refs hash' do - expect(entry.value).to eq(refs: config) - end - end - end - - context 'when config is a regexp' do - let(:config) { ['/^issue-.*$/'] } - - describe '#valid?' do - it 'is valid' do - expect(entry).to be_valid - end - end - end - - context 'when config is a special keyword' do - let(:config) { %w[tags triggers branches] } - - describe '#valid?' do - it 'is valid' do - expect(entry).to be_valid - end - end - end - end - - context 'when entry value is not valid' do - let(:config) { [1] } - - describe '#errors' do - it 'saves errors' do - expect(entry.errors) - .to include /policy config should be an array of strings or regexps/ - end - end - end - end - end - - context 'when using complex policy' do - context 'when specifying refs policy' do - let(:config) { { refs: ['master'] } } - - it 'is a correct configuraton' do - expect(entry).to be_valid - expect(entry.value).to eq(refs: %w[master]) - end - end - - context 'when specifying kubernetes policy' do - let(:config) { { kubernetes: 'active' } } - - it 'is a correct configuraton' do - expect(entry).to be_valid - expect(entry.value).to eq(kubernetes: 'active') - end - end - - context 'when specifying invalid kubernetes policy' do - let(:config) { { kubernetes: 'something' } } - - it 'reports an error about invalid policy' do - expect(entry.errors).to include /unknown value: something/ - end - end - - context 'when specifying valid variables expressions policy' do - let(:config) { { variables: ['$VAR == null'] } } - - it 'is a correct configuraton' do - expect(entry).to be_valid - expect(entry.value).to eq(config) - end - end - - context 'when specifying variables expressions in invalid format' do - let(:config) { { variables: '$MY_VAR' } } - - it 'reports an error about invalid format' do - expect(entry.errors).to include /should be an array of strings/ - end - end - - context 'when specifying invalid variables expressions statement' do - let(:config) { { variables: ['$MY_VAR =='] } } - - it 'reports an error about invalid statement' do - expect(entry.errors).to include /invalid expression syntax/ - end - end - - context 'when specifying invalid variables expressions token' do - let(:config) { { variables: ['$MY_VAR == 123'] } } - - it 'reports an error about invalid expression' do - expect(entry.errors).to include /invalid expression syntax/ - end - end - - context 'when using invalid variables expressions regexp' do - let(:config) { { variables: ['$MY_VAR =~ /some ( thing/'] } } - - it 'reports an error about invalid expression' do - expect(entry.errors).to include /invalid expression syntax/ - end - end - - context 'when specifying a valid changes policy' do - let(:config) { { changes: %w[some/* paths/**/*.rb] } } - - it 'is a correct configuraton' do - expect(entry).to be_valid - expect(entry.value).to eq(config) - end - end - - context 'when changes policy is invalid' do - let(:config) { { changes: [1, 2] } } - - it 'returns errors' do - expect(entry.errors).to include /changes should be an array of strings/ - end - end - - context 'when specifying unknown policy' do - let(:config) { { refs: ['master'], invalid: :something } } - - it 'returns error about invalid key' do - expect(entry.errors).to include /unknown keys: invalid/ - end - end - - context 'when policy is empty' do - let(:config) { {} } - - it 'is not a valid configuration' do - expect(entry.errors).to include /can't be blank/ - end - end - end - - context 'when policy strategy does not match' do - let(:config) { 'string strategy' } - - it 'returns information about errors' do - expect(entry.errors) - .to include /has to be either an array of conditions or a hash/ - end - end -end diff --git a/spec/support/shared_examples/policies/clusterable_shared_examples.rb b/spec/support/shared_examples/policies/clusterable_shared_examples.rb new file mode 100644 index 00000000000..d99f94c76c3 --- /dev/null +++ b/spec/support/shared_examples/policies/clusterable_shared_examples.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +shared_examples 'clusterable policies' do + describe '#add_cluster?' do + let(:current_user) { create(:user) } + + subject { described_class.new(current_user, clusterable) } + + context 'with a developer' do + before do + clusterable.add_developer(current_user) + end + + it { expect_disallowed(:add_cluster) } + end + + context 'with a maintainer' do + before do + clusterable.add_maintainer(current_user) + end + + context 'with no clusters' do + it { expect_allowed(:add_cluster) } + end + + context 'with an existing cluster' do + before do + cluster + end + + it { expect_disallowed(:add_cluster) } + end + end + end +end diff --git a/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb index 9fc2fbef449..8a7fcf856a1 100644 --- a/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb @@ -9,7 +9,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name| context 'with an unauthorized user' do it 'does not filter by custom attributes' do - get api("/#{attributable_name}", user), custom_attributes: { foo: 'foo', bar: 'bar' } + get api("/#{attributable_name}", user), params: { custom_attributes: { foo: 'foo', bar: 'bar' } } expect(response).to have_gitlab_http_status(200) expect(json_response.size).to be 2 @@ -19,7 +19,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name| context 'with an authorized user' do it 'filters by custom attributes' do - get api("/#{attributable_name}", admin), custom_attributes: { foo: 'foo', bar: 'bar' } + get api("/#{attributable_name}", admin), params: { custom_attributes: { foo: 'foo', bar: 'bar' } } expect(response).to have_gitlab_http_status(200) expect(json_response.size).to be 1 @@ -35,7 +35,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name| context 'with an unauthorized user' do it 'does not include custom attributes' do - get api("/#{attributable_name}", user), with_custom_attributes: true + get api("/#{attributable_name}", user), params: { with_custom_attributes: true } expect(response).to have_gitlab_http_status(200) expect(json_response.size).to be 2 @@ -54,7 +54,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name| end it 'includes custom attributes if requested' do - get api("/#{attributable_name}", admin), with_custom_attributes: true + get api("/#{attributable_name}", admin), params: { with_custom_attributes: true } expect(response).to have_gitlab_http_status(200) expect(json_response.size).to be 2 @@ -75,7 +75,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name| describe "GET /#{attributable_name}/:id with custom attributes" do context 'with an unauthorized user' do it 'does not include custom attributes' do - get api("/#{attributable_name}/#{attributable.id}", user), with_custom_attributes: true + get api("/#{attributable_name}/#{attributable.id}", user), params: { with_custom_attributes: true } expect(response).to have_gitlab_http_status(200) expect(json_response).not_to include 'custom_attributes' @@ -91,7 +91,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name| end it 'includes custom attributes if requested' do - get api("/#{attributable_name}/#{attributable.id}", admin), with_custom_attributes: true + get api("/#{attributable_name}/#{attributable.id}", admin), params: { with_custom_attributes: true } expect(response).to have_gitlab_http_status(200) expect(json_response['custom_attributes']).to contain_exactly( @@ -141,7 +141,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name| describe "PUT /#{attributable_name}/:id/custom_attributes/:key" do context 'with an unauthorized user' do - subject { put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", user), value: 'new' } + subject { put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", user), params: { value: 'new' } } it_behaves_like 'an unauthorized API user' end @@ -149,7 +149,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name| context 'with an authorized user' do it 'creates a new custom attribute' do expect do - put api("/#{attributable_name}/#{attributable.id}/custom_attributes/new", admin), value: 'new' + put api("/#{attributable_name}/#{attributable.id}/custom_attributes/new", admin), params: { value: 'new' } end.to change { attributable.custom_attributes.count }.by(1) expect(response).to have_gitlab_http_status(200) @@ -159,7 +159,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name| it 'updates an existing custom attribute' do expect do - put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin), value: 'new' + put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin), params: { value: 'new' } end.not_to change { attributable.custom_attributes.count } expect(response).to have_gitlab_http_status(200) diff --git a/spec/support/shared_examples/requests/api/diff_discussions.rb b/spec/support/shared_examples/requests/api/diff_discussions.rb index 85a4bd8ca27..366c2955359 100644 --- a/spec/support/shared_examples/requests/api/diff_discussions.rb +++ b/spec/support/shared_examples/requests/api/diff_discussions.rb @@ -27,7 +27,8 @@ shared_examples 'diff discussions API' do |parent_type, noteable_type, id_name| it "creates a new diff note" do position = diff_note.position.to_h - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), body: 'hi!', position: position + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), + params: { body: 'hi!', position: position } expect(response).to have_gitlab_http_status(201) expect(json_response['notes'].first['body']).to eq('hi!') @@ -38,7 +39,8 @@ shared_examples 'diff discussions API' do |parent_type, noteable_type, id_name| it "returns a 400 bad request error when position is invalid" do position = diff_note.position.to_h.merge(new_line: '100000') - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), body: 'hi!', position: position + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), + params: { body: 'hi!', position: position } expect(response).to have_gitlab_http_status(400) end @@ -47,7 +49,7 @@ shared_examples 'diff discussions API' do |parent_type, noteable_type, id_name| describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes" do it 'adds a new note to the diff discussion' do post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{diff_note.discussion_id}/notes", user), body: 'hi!' + "discussions/#{diff_note.discussion_id}/notes", user), params: { body: 'hi!' } expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq('hi!') diff --git a/spec/support/shared_examples/requests/api/discussions.rb b/spec/support/shared_examples/requests/api/discussions.rb index b6aeb30d69c..e44da4faa5a 100644 --- a/spec/support/shared_examples/requests/api/discussions.rb +++ b/spec/support/shared_examples/requests/api/discussions.rb @@ -42,7 +42,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name| describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions" do it "creates a new note" do - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), body: 'hi!' + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), params: { body: 'hi!' } expect(response).to have_gitlab_http_status(201) expect(json_response['notes'].first['body']).to eq('hi!') @@ -56,7 +56,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name| end it "returns a 401 unauthorized error if user not authenticated" do - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions"), body: 'hi!' + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions"), params: { body: 'hi!' } expect(response).to have_gitlab_http_status(401) end @@ -65,7 +65,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name| it 'accepts the creation date to be set' do creation_time = 2.weeks.ago post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), - body: 'hi!', created_at: creation_time + params: { body: 'hi!', created_at: creation_time } expect(response).to have_gitlab_http_status(201) expect(json_response['notes'].first['body']).to eq('hi!') @@ -81,7 +81,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name| it 'responds with 404' do post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", private_user), - body: 'Foo' + params: { body: 'Foo' } expect(response).to have_gitlab_http_status(404) end @@ -91,7 +91,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name| describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes" do it 'adds a new note to the discussion' do post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}/notes", user), body: 'Hello!' + "discussions/#{note.discussion_id}/notes", user), params: { body: 'Hello!' } expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq('Hello!') @@ -109,7 +109,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name| note.update_attribute(:type, nil) post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}/notes", user), body: 'hi!' + "discussions/#{note.discussion_id}/notes", user), params: { body: 'hi!' } expect(response).to have_gitlab_http_status(400) end @@ -118,7 +118,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name| describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes/:note_id" do it 'returns modified note' do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}/notes/#{note.id}", user), body: 'Hello!' + "discussions/#{note.discussion_id}/notes/#{note.id}", user), params: { body: 'Hello!' } expect(response).to have_gitlab_http_status(200) expect(json_response['body']).to eq('Hello!') @@ -127,7 +127,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name| it 'returns a 404 error when note id not found' do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ "discussions/#{note.discussion_id}/notes/12345", user), - body: 'Hello!' + params: { body: 'Hello!' } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/support/shared_examples/requests/api/merge_requests_list.rb b/spec/support/shared_examples/requests/api/merge_requests_list.rb index 92d4dd598d5..453f42251c8 100644 --- a/spec/support/shared_examples/requests/api/merge_requests_list.rb +++ b/spec/support/shared_examples/requests/api/merge_requests_list.rb @@ -123,7 +123,7 @@ shared_examples 'merge requests list' do end it 'returns an empty array if no issue matches milestone' do - get api(endpoint_path, user), milestone: '1.0.0' + get api(endpoint_path, user), params: { milestone: '1.0.0' } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -131,7 +131,7 @@ shared_examples 'merge requests list' do end it 'returns an empty array if milestone does not exist' do - get api(endpoint_path, user), milestone: 'foo' + get api(endpoint_path, user), params: { milestone: 'foo' } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -139,7 +139,7 @@ shared_examples 'merge requests list' do end it 'returns an array of merge requests in given milestone' do - get api(endpoint_path, user), milestone: '0.9' + get api(endpoint_path, user), params: { milestone: '0.9' } closed_issues = json_response.select { |mr| mr['id'] == merge_request_closed.id } expect(closed_issues.length).to eq(1) @@ -147,7 +147,7 @@ shared_examples 'merge requests list' do end it 'returns an array of merge requests matching state in milestone' do - get api(endpoint_path, user), milestone: '0.9', state: 'closed' + get api(endpoint_path, user), params: { milestone: '0.9', state: 'closed' } expect(response).to have_gitlab_http_status(200) expect(json_response).to be_an Array @@ -187,7 +187,7 @@ shared_examples 'merge requests list' do end it 'returns an array of merge requests with any label when filtering by any label' do - get api(endpoint_path, user), labels: IssuesFinder::FILTER_ANY + get api(endpoint_path, user), params: { labels: IssuesFinder::FILTER_ANY } expect_paginated_array_response expect(json_response.length).to eq(1) @@ -195,7 +195,7 @@ shared_examples 'merge requests list' do end it 'returns an array of merge requests without a label when filtering by no label' do - get api(endpoint_path, user), labels: IssuesFinder::FILTER_NONE + get api(endpoint_path, user), params: { labels: IssuesFinder::FILTER_NONE } response_ids = json_response.map { |merge_request| merge_request['id'] } @@ -286,7 +286,7 @@ shared_examples 'merge requests list' do context 'source_branch param' do it 'returns merge requests with the given source branch' do - get api(endpoint_path, user), source_branch: merge_request_closed.source_branch, state: 'all' + get api(endpoint_path, user), params: { source_branch: merge_request_closed.source_branch, state: 'all' } expect_response_contain_exactly(merge_request_closed, merge_request_merged, merge_request_locked) end @@ -294,7 +294,7 @@ shared_examples 'merge requests list' do context 'target_branch param' do it 'returns merge requests with the given target branch' do - get api(endpoint_path, user), target_branch: merge_request_closed.target_branch, state: 'all' + get api(endpoint_path, user), params: { target_branch: merge_request_closed.target_branch, state: 'all' } expect_response_contain_exactly(merge_request_closed, merge_request_merged, merge_request_locked) end diff --git a/spec/support/shared_examples/requests/api/notes.rb b/spec/support/shared_examples/requests/api/notes.rb index 0e20dfe0725..71499e85654 100644 --- a/spec/support/shared_examples/requests/api/notes.rb +++ b/spec/support/shared_examples/requests/api/notes.rb @@ -86,7 +86,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes" do it "creates a new note" do - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: 'hi!' + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: { body: 'hi!' } expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq('hi!') @@ -100,7 +100,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| end it "returns a 401 unauthorized error if user not authenticated" do - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes"), body: 'hi!' + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes"), params: { body: 'hi!' } expect(response).to have_gitlab_http_status(401) end @@ -108,7 +108,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| it "creates an activity event when a note is created" do expect(Event).to receive(:create!) - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: 'hi!' + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: { body: 'hi!' } end context 'setting created_at' do @@ -118,7 +118,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| context 'by an admin' do it 'sets the creation time on the new note' do admin = create(:admin) - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", admin), params + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", admin), params: params expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq('hi!') @@ -131,7 +131,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| if parent_type == 'projects' context 'by a project owner' do it 'sets the creation time on the new note' do - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq('hi!') @@ -149,7 +149,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| parent.update!(namespace: group) user2.refresh_authorized_projects - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params: params expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq('hi!') @@ -161,7 +161,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| elsif parent_type == 'groups' context 'by a group owner' do it 'sets the creation time on the new note' do - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq('hi!') @@ -176,7 +176,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| it 'ignores the given creation time' do user2 = create(:user) parent.add_developer(user2) - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params: params expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq('hi!') @@ -190,7 +190,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| context 'when the user is posting an award emoji on a noteable created by someone else' do it 'creates a new note' do parent.add_developer(private_user) - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user), body: ':+1:' + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user), params: { body: ':+1:' } expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq(':+1:') @@ -199,7 +199,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| context 'when the user is posting an award emoji on his/her own noteable' do it 'creates a new note' do - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: ':+1:' + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: { body: ':+1:' } expect(response).to have_gitlab_http_status(201) expect(json_response['body']).to eq(':+1:') @@ -213,7 +213,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| it 'responds with 404' do post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user), - body: 'Foo' + params: { body: 'Foo' } expect(response).to have_gitlab_http_status(404) end @@ -223,7 +223,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id" do it 'returns modified note' do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "notes/#{note.id}", user), body: 'Hello!' + "notes/#{note.id}", user), params: { body: 'Hello!' } expect(response).to have_gitlab_http_status(200) expect(json_response['body']).to eq('Hello!') @@ -231,7 +231,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| it 'returns a 404 error when note id not found' do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/12345", user), - body: 'Hello!' + params: { body: 'Hello!' } expect(response).to have_gitlab_http_status(404) end diff --git a/spec/support/shared_examples/requests/api/resolvable_discussions.rb b/spec/support/shared_examples/requests/api/resolvable_discussions.rb index 408ad08cc48..7e2416b23f3 100644 --- a/spec/support/shared_examples/requests/api/resolvable_discussions.rb +++ b/spec/support/shared_examples/requests/api/resolvable_discussions.rb @@ -2,7 +2,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_ describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id" do it "resolves discussion if resolved is true" do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}", user), resolved: true + "discussions/#{note.discussion_id}", user), params: { resolved: true } expect(response).to have_gitlab_http_status(200) expect(json_response['notes'].size).to eq(1) @@ -11,7 +11,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_ it "unresolves discussion if resolved is false" do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}", user), resolved: false + "discussions/#{note.discussion_id}", user), params: { resolved: false } expect(response).to have_gitlab_http_status(200) expect(json_response['notes'].size).to eq(1) @@ -27,14 +27,14 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_ it "returns a 401 unauthorized error if user is not authenticated" do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}"), resolved: true + "discussions/#{note.discussion_id}"), params: { resolved: true } expect(response).to have_gitlab_http_status(401) end it "returns a 403 error if user resolves discussion of someone else" do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}", private_user), resolved: true + "discussions/#{note.discussion_id}", private_user), params: { resolved: true } expect(response).to have_gitlab_http_status(403) end @@ -46,7 +46,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_ it 'responds with 404' do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}", private_user), resolved: true + "discussions/#{note.discussion_id}", private_user), params: { resolved: true } expect(response).to have_gitlab_http_status(404) end @@ -56,7 +56,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_ describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes/:note_id" do it 'returns resolved note when resolved parameter is true' do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}/notes/#{note.id}", user), resolved: true + "discussions/#{note.discussion_id}/notes/#{note.id}", user), params: { resolved: true } expect(response).to have_gitlab_http_status(200) expect(json_response['resolved']).to eq(true) @@ -65,7 +65,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_ it 'returns a 404 error when note id not found' do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ "discussions/#{note.discussion_id}/notes/12345", user), - body: 'Hello!' + params: { body: 'Hello!' } expect(response).to have_gitlab_http_status(404) end @@ -79,7 +79,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_ it "returns a 403 error if user resolves note of someone else" do put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ - "discussions/#{note.discussion_id}/notes/#{note.id}", private_user), resolved: true + "discussions/#{note.discussion_id}/notes/#{note.id}", private_user), params: { resolved: true } expect(response).to have_gitlab_http_status(403) end diff --git a/spec/support/shared_examples/requests/api/status_shared_examples.rb b/spec/support/shared_examples/requests/api/status_shared_examples.rb index 0ed917e448a..ebfc5fed3bb 100644 --- a/spec/support/shared_examples/requests/api/status_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/status_shared_examples.rb @@ -54,7 +54,7 @@ shared_examples_for '412 response' do context 'for a modified ressource' do before do - delete request, params, { 'HTTP_IF_UNMODIFIED_SINCE' => '1990-01-12T00:00:48-0600' } + delete request, params: params, headers: { 'HTTP_IF_UNMODIFIED_SINCE' => '1990-01-12T00:00:48-0600' } end it 'returns 412' do @@ -64,7 +64,7 @@ shared_examples_for '412 response' do context 'for an unmodified ressource' do before do - delete request, params, { 'HTTP_IF_UNMODIFIED_SINCE' => Time.now } + delete request, params: params, headers: { 'HTTP_IF_UNMODIFIED_SINCE' => Time.now } end it 'returns accepted' do diff --git a/spec/support/shared_examples/serializers/diff_file_entity_examples.rb b/spec/support/shared_examples/serializers/diff_file_entity_examples.rb index b8065886c42..1770308f789 100644 --- a/spec/support/shared_examples/serializers/diff_file_entity_examples.rb +++ b/spec/support/shared_examples/serializers/diff_file_entity_examples.rb @@ -32,7 +32,7 @@ shared_examples 'diff file entity' do it 'exposes correct attributes' do expect(subject).to include(:too_large, :added_lines, :removed_lines, :context_lines_path, :highlighted_diff_lines, - :parallel_diff_lines) + :parallel_diff_lines, :empty) end it 'includes viewer' do diff --git a/spec/support/shared_examples/update_invalid_issuable.rb b/spec/support/shared_examples/update_invalid_issuable.rb index 1490287681b..64568de424e 100644 --- a/spec/support/shared_examples/update_invalid_issuable.rb +++ b/spec/support/shared_examples/update_invalid_issuable.rb @@ -26,7 +26,7 @@ shared_examples 'update invalid issuable' do |klass| end it 'renders edit when format is html' do - put :update, params + put :update, params: params expect(response).to render_template(:edit) expect(assigns[:conflict]).to be_truthy @@ -35,7 +35,7 @@ shared_examples 'update invalid issuable' do |klass| it 'renders json error message when format is json' do params[:format] = "json" - put :update, params + put :update, params: params expect(response.status).to eq(409) expect(JSON.parse(response.body)).to have_key('errors') @@ -49,7 +49,7 @@ shared_examples 'update invalid issuable' do |klass| end it 'renders edit when merge request is invalid' do - put :update, params + put :update, params: params expect(response).to render_template(:edit) end diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb index 8c4360d4cf0..3b8f7f5fe7d 100644 --- a/spec/tasks/gitlab/backup_rake_spec.rb +++ b/spec/tasks/gitlab/backup_rake_spec.rb @@ -74,6 +74,7 @@ describe 'gitlab:app namespace rake task' do it 'invokes restoration on match' do allow(YAML).to receive(:load_file) .and_return({ gitlab_version: gitlab_version }) + expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke) expect(Rake::Task['gitlab:backup:db:restore']).to receive(:invoke) expect(Rake::Task['gitlab:backup:repo:restore']).to receive(:invoke) diff --git a/spec/tasks/gitlab/storage_rake_spec.rb b/spec/tasks/gitlab/storage_rake_spec.rb index 233076ad6fa..be902d7c679 100644 --- a/spec/tasks/gitlab/storage_rake_spec.rb +++ b/spec/tasks/gitlab/storage_rake_spec.rb @@ -46,6 +46,16 @@ describe 'rake gitlab:storage:*' do describe 'gitlab:storage:migrate_to_hashed' do let(:task) { 'gitlab:storage:migrate_to_hashed' } + context 'read-only database' do + it 'does nothing' do + expect(Gitlab::Database).to receive(:read_only?).and_return(true) + + expect(Project).not_to receive(:with_unmigrated_storage) + + expect { run_rake_task(task) }.to output(/This task requires database write access. Exiting./).to_stderr + end + end + context '0 legacy projects' do it 'does nothing' do expect(StorageMigratorWorker).not_to receive(:perform_async) @@ -92,7 +102,7 @@ describe 'rake gitlab:storage:*' do stub_env('ID_FROM', 99999) stub_env('ID_TO', 99999) - expect { run_rake_task(task) }.to output(/There are no projects requiring storage migration with ID=99999/).to_stdout + expect { run_rake_task(task) }.to output(/There are no projects requiring storage migration with ID=99999/).to_stderr end it 'displays a message when project exists but its already migrated' do @@ -100,7 +110,7 @@ describe 'rake gitlab:storage:*' do stub_env('ID_FROM', project.id) stub_env('ID_TO', project.id) - expect { run_rake_task(task) }.to output(/There are no projects requiring storage migration with ID=#{project.id}/).to_stdout + expect { run_rake_task(task) }.to output(/There are no projects requiring storage migration with ID=#{project.id}/).to_stderr end it 'enqueues migration when project can be found' do diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb index 98d4456b277..ec20c346234 100644 --- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb +++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb @@ -49,4 +49,30 @@ describe 'layouts/nav/sidebar/_project' do expect(rendered).to have_css('.sidebar-top-level-items > li.active', text: 'Registry') end end + + describe 'releases entry' do + describe 'when releases feature flag is disabled' do + before do + stub_feature_flags(releases_page: false) + end + + it 'does not render releases link' do + render + + expect(rendered).not_to have_link('Releases', href: project_releases_path(project)) + end + end + + describe 'when releases feature flags is enabled' do + before do + stub_feature_flags(releases_page: true) + end + + it 'renders releases link' do + render + + expect(rendered).to have_link('Releases', href: project_releases_path(project)) + end + end + end end diff --git a/spec/views/notify/changed_milestone_email.html.haml_spec.rb b/spec/views/notify/changed_milestone_email.html.haml_spec.rb new file mode 100644 index 00000000000..194b58840a3 --- /dev/null +++ b/spec/views/notify/changed_milestone_email.html.haml_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'notify/changed_milestone_email.html.haml' do + let(:milestone) { create(:milestone, title: 'some-milestone') } + let(:milestone_link) { milestone_url(milestone) } + + before do + assign(:milestone, milestone) + assign(:milestone_url, milestone_link) + end + + context 'milestone without start and due dates' do + it 'renders without date range' do + render + + expect(rendered).to have_content('Milestone changed to some-milestone', exact: true) + expect(rendered).to have_link('some-milestone', href: milestone_link) + end + end + + context 'milestone with start and due dates' do + before do + milestone.update(start_date: '2018-01-01', due_date: '2018-12-31') + end + + it 'renders with date range' do + render + + expect(rendered).to have_content('Milestone changed to some-milestone (Jan 1, 2018–Dec 31, 2018)', exact: true) + expect(rendered).to have_link('some-milestone', href: milestone_link) + end + end +end diff --git a/spec/views/projects/merge_requests/show.html.haml_spec.rb b/spec/views/projects/merge_requests/show.html.haml_spec.rb index fa6c4ce4ac8..b0042be339c 100644 --- a/spec/views/projects/merge_requests/show.html.haml_spec.rb +++ b/spec/views/projects/merge_requests/show.html.haml_spec.rb @@ -32,6 +32,11 @@ describe 'projects/merge_requests/show.html.haml' do assign(:noteable, closed_merge_request) assign(:notes, []) assign(:pipelines, Ci::Pipeline.none) + assign( + :issuable_sidebar, + MergeRequestSerializer.new(current_user: user, project: project) + .represent(closed_merge_request, serializer: 'sidebar') + ) preload_view_requirements diff --git a/spec/workers/cluster_platform_configure_worker_spec.rb b/spec/workers/cluster_configure_worker_spec.rb index 0eead0ab13d..6918ee3d7d8 100644 --- a/spec/workers/cluster_platform_configure_worker_spec.rb +++ b/spec/workers/cluster_configure_worker_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe ClusterPlatformConfigureWorker, '#perform' do +describe ClusterConfigureWorker, '#perform' do let(:worker) { described_class.new } context 'when group cluster' do diff --git a/spec/workers/cluster_provision_worker_spec.rb b/spec/workers/cluster_provision_worker_spec.rb index 0a2dfef36a4..da32f29fec0 100644 --- a/spec/workers/cluster_provision_worker_spec.rb +++ b/spec/workers/cluster_provision_worker_spec.rb @@ -23,7 +23,7 @@ describe ClusterProvisionWorker do end it 'configures kubernetes platform' do - expect(ClusterPlatformConfigureWorker).to receive(:perform_async).with(cluster.id) + expect(ClusterConfigureWorker).to receive(:perform_async).with(cluster.id) described_class.new.perform(cluster.id) end @@ -32,7 +32,7 @@ describe ClusterProvisionWorker do context 'when cluster does not exist' do it 'does not provision a cluster' do expect_any_instance_of(Clusters::Gcp::ProvisionService).not_to receive(:execute) - expect(ClusterPlatformConfigureWorker).not_to receive(:perform_async) + expect(ClusterConfigureWorker).not_to receive(:perform_async) described_class.new.perform(123) end diff --git a/spec/workers/object_pool/destroy_worker_spec.rb b/spec/workers/object_pool/destroy_worker_spec.rb new file mode 100644 index 00000000000..ef74f0ba87c --- /dev/null +++ b/spec/workers/object_pool/destroy_worker_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +describe ObjectPool::DestroyWorker do + describe '#perform' do + context 'when no pool is in the database' do + it "doesn't raise an error" do + expect do + described_class.new.perform(987654321) + end.not_to raise_error + end + end + + context 'when a pool is present' do + let(:pool) { create(:pool_repository, :obsolete) } + + subject { described_class.new } + + it 'requests Gitaly to remove the object pool' do + expect(Gitlab::GitalyClient).to receive(:call).with(pool.shard_name, :object_pool_service, :delete_object_pool, Object) + + subject.perform(pool.id) + end + + it 'destroys the pool' do + subject.perform(pool.id) + + expect(PoolRepository.find_by_id(pool.id)).to be_nil + end + end + end +end diff --git a/spec/workers/repository_update_remote_mirror_worker_spec.rb b/spec/workers/repository_update_remote_mirror_worker_spec.rb index 4f1ad2474f5..d73b0b53713 100644 --- a/spec/workers/repository_update_remote_mirror_worker_spec.rb +++ b/spec/workers/repository_update_remote_mirror_worker_spec.rb @@ -25,12 +25,19 @@ describe RepositoryUpdateRemoteMirrorWorker do it 'sets status as failed when update remote mirror service executes with errors' do error_message = 'fail!' - expect_any_instance_of(Projects::UpdateRemoteMirrorService).to receive(:execute).with(remote_mirror).and_return(status: :error, message: error_message) + expect_next_instance_of(Projects::UpdateRemoteMirrorService) do |service| + expect(service).to receive(:execute).with(remote_mirror).and_return(status: :error, message: error_message) + end + + # Mock the finder so that it returns an object we can set expectations on + expect_next_instance_of(RemoteMirrorFinder) do |finder| + expect(finder).to receive(:execute).and_return(remote_mirror) + end + expect(remote_mirror).to receive(:mark_as_failed).with(error_message) + expect do subject.perform(remote_mirror.id, Time.now) end.to raise_error(RepositoryUpdateRemoteMirrorWorker::UpdateError, error_message) - - expect(remote_mirror.reload.update_status).to eq('failed') end it 'does nothing if last_update_started_at is higher than the time the job was scheduled in' do diff --git a/spec/workers/stuck_merge_jobs_worker_spec.rb b/spec/workers/stuck_merge_jobs_worker_spec.rb index c2c2a5f9121..5aaff27a6b2 100644 --- a/spec/workers/stuck_merge_jobs_worker_spec.rb +++ b/spec/workers/stuck_merge_jobs_worker_spec.rb @@ -38,7 +38,8 @@ describe StuckMergeJobsWorker do create(:merge_request, :locked, merge_jid: '123') create(:merge_request, :locked, merge_jid: '456') - expect(Rails).to receive_message_chain(:logger, :info).with('Updated state of locked merge jobs. JIDs: 123, 456') + expect(described_class).to receive_message_chain(:logger, :info) + .with('Updated state of locked merge jobs. JIDs: 123, 456') worker.perform end |