# frozen_string_literal: true require 'spec_helper' describe Projects::Settings::OperationsController do set(:user) { create(:user) } before do sign_in(user) end describe 'GET show' do shared_examples 'user without read access' do |project_visibility| let(:project) { create(:project, project_visibility) } %w[guest reporter developer].each do |role| before do project.public_send("add_#{role}", user) end it 'returns 404' do get :show, params: project_params(project) expect(response).to have_gitlab_http_status(:not_found) end end end shared_examples 'user with read access' do |project_visibility| let(:project) { create(:project, project_visibility) } before do project.add_maintainer(user) end it 'renders ok' do get :show, params: project_params(project) expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:show) end end shared_examples 'user needs to login' do |project_visibility| it 'redirects for private project' do project = create(:project, project_visibility) get :show, params: project_params(project) expect(response).to redirect_to(new_user_session_path) end end context 'with a license' do before do stub_licensed_features(tracing: true) end context 'with maintainer role' do it_behaves_like 'user with read access', :public it_behaves_like 'user with read access', :private it_behaves_like 'user with read access', :internal end context 'without maintainer role' do it_behaves_like 'user without read access', :public it_behaves_like 'user without read access', :private it_behaves_like 'user without read access', :internal end context 'when user not logged in' do before do sign_out(user) end it_behaves_like 'user without read access', :public it_behaves_like 'user needs to login', :private it_behaves_like 'user needs to login', :internal end end context 'without license' do before do stub_licensed_features(tracing: false) end it_behaves_like 'user without read access', :public it_behaves_like 'user without read access', :private it_behaves_like 'user without read access', :internal end end describe 'PATCH update' do let(:public_project) { create(:project, :public) } let(:private_project) { create(:project, :private) } let(:internal_project) { create(:project, :internal) } before do public_project.add_maintainer(user) private_project.add_maintainer(user) internal_project.add_maintainer(user) end shared_examples 'user without write access' do |project_visibility| let(:project) { create(:project, project_visibility) } %w[guest reporter developer].each do |role| before do project.public_send("add_#{role}", user) end it 'does not update tracing external_url' do update_project(project, external_url: 'https://gitlab.com') expect(project.tracing_setting).to be_nil end end end context 'with a license' do before do stub_licensed_features(tracing: true) end shared_examples 'user with write access' do |project_visibility, value_to_set, value_to_check| let(:project) { create(:project, project_visibility) } before do project.add_maintainer(user) end it 'updates tracing external_url' do update_project(project, external_url: value_to_set) expect(project.tracing_setting.external_url).to eq(value_to_check) end end context 'with maintainer role' do it_behaves_like 'user with write access', :public, 'https://gitlab.com', 'https://gitlab.com' it_behaves_like 'user with write access', :private, 'https://gitlab.com', 'https://gitlab.com' it_behaves_like 'user with write access', :internal, 'https://gitlab.com', 'https://gitlab.com' end context 'with non maintainer roles' do it_behaves_like 'user without write access', :public it_behaves_like 'user without write access', :private it_behaves_like 'user without write access', :internal end context 'with anonymous user' do before do sign_out(user) end it_behaves_like 'user without write access', :public it_behaves_like 'user without write access', :private it_behaves_like 'user without write access', :internal end context 'with existing tracing_setting' do let(:project) { create(:project) } before do project.create_tracing_setting!(external_url: 'https://gitlab.com') project.add_maintainer(user) end it 'unsets external_url with nil' do update_project(project, external_url: nil) expect(project.tracing_setting).to be_nil end it 'unsets external_url with empty string' do update_project(project, external_url: '') expect(project.tracing_setting).to be_nil end it 'fails validation with invalid url' do expect do update_project(project, external_url: "invalid") end.not_to change(project.tracing_setting, :external_url) end it 'does not set external_url if not present in params' do expect do update_project(project, some_param: 'some_value') end.not_to change(project.tracing_setting, :external_url) end end context 'without existing tracing_setting' do let(:project) { create(:project) } before do project.add_maintainer(user) end it 'fails validation with invalid url' do update_project(project, external_url: "invalid") expect(project.tracing_setting).to be_nil end it 'does not set external_url if not present in params' do update_project(project, some_param: 'some_value') expect(project.tracing_setting).to be_nil end end end context 'without a license' do before do stub_licensed_features(tracing: false) end it_behaves_like 'user without write access', :public it_behaves_like 'user without write access', :private it_behaves_like 'user without write access', :internal end private def update_project(project, params) patch :update, params: project_params(project, params) project.reload end end describe 'POST reset_alerting_token' do let(:project) { create(:project) } before do stub_licensed_features(prometheus_alerts: true) project.add_maintainer(user) end context 'with existing alerting setting' do let!(:alerting_setting) do create(:project_alerting_setting, project: project) end let!(:old_token) { alerting_setting.token } it 'returns newly reset token' do reset_alerting_token expect(response).to have_gitlab_http_status(:ok) expect(json_response['token']).to eq(alerting_setting.reload.token) expect(old_token).not_to eq(alerting_setting.token) end end context 'without existing alerting setting' do it 'creates a token' do reset_alerting_token expect(response).to have_gitlab_http_status(:ok) expect(project.alerting_setting).not_to be_nil expect(json_response['token']).to eq(project.alerting_setting.token) end end context 'when update fails' do let(:operations_update_service) { spy(:operations_update_service) } let(:alerting_params) do { alerting_setting_attributes: { regenerate_token: true } } end before do expect(::Projects::Operations::UpdateService) .to receive(:new).with(project, user, alerting_params) .and_return(operations_update_service) expect(operations_update_service).to receive(:execute) .and_return(status: :error) end it 'returns unprocessable_entity' do reset_alerting_token expect(response).to have_gitlab_http_status(:unprocessable_entity) expect(json_response).to be_empty end end context 'with insufficient permissions' do before do project.add_reporter(user) end it 'returns 404' do reset_alerting_token expect(response).to have_gitlab_http_status(:not_found) end end context 'as an anonymous user' do before do sign_out(user) end it 'returns unauthorized status' do reset_alerting_token expect(response).to have_gitlab_http_status(:unauthorized) end end context 'without a license' do before do stub_licensed_features(prometheus_alerts: false) end it 'returns 404' do reset_alerting_token expect(response).to have_gitlab_http_status(:not_found) end end private def reset_alerting_token post :reset_alerting_token, params: project_params(project), format: :json end end private def project_params(project, params = {}) { namespace_id: project.namespace, project_id: project, project: { tracing_setting_attributes: params } } end end