Commit 17cb89f8 authored by Peter Leitzen's avatar Peter Leitzen

Merge branch 'enable-disable-error-tracking-api' into 'master'

API to enable and disable error tracking settings

See merge request gitlab-org/gitlab!24220
parents bfa25b35 cbf93adf
......@@ -30,6 +30,27 @@ module Projects
settings = params[:error_tracking_setting_attributes]
return {} if settings.blank?
if error_tracking_params_partial_updates?(settings)
error_tracking_params_for_partial_update(settings)
else
error_tracking_params_for_update(settings)
end
end
def error_tracking_params_partial_updates?(settings)
# Help from @splattael :bow:
# Make sure we're converting to symbols because
# * ActionController::Parameters#keys returns a list of strings
# * in specs we're using hashes with symbols as keys
settings.keys.map(&:to_sym) == %i[enabled]
end
def error_tracking_params_for_partial_update(settings)
{ error_tracking_setting_attributes: settings }
end
def error_tracking_params_for_update(settings)
api_url = ::ErrorTracking::ProjectErrorTrackingSetting.build_api_url_from(
api_host: settings[:api_host],
project_slug: settings.dig(:project, :slug),
......
---
title: Add API to enable and disable error tracking settings
merge_request: 24220
author: Rajendra Kadam
type: added
......@@ -30,3 +30,31 @@ Example response:
"api_url": "https://sentry.io/api/0/projects/myawesomeproject/project"
}
```
### Enable or disable the Error Tracking project settings
The API allows you to enable or disable the Error Tracking settings for a project. Only for project maintainers.
```
PATCH /projects/:id/error_tracking/settings
```
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- |
| `id` | integer | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
| `active` | boolean | yes | Pass `true` to enable the already configured error tracking settings or `false` to disable it. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/error_tracking/settings?active=true
```
Example response:
```json
{
"active": true,
"project_name": "sample sentry project",
"sentry_external_url": "https://sentry.io/myawesomeproject/project",
"api_url": "https://sentry.io/api/0/projects/myawesomeproject/project"
}
```
......@@ -23,6 +23,34 @@ module API
present setting, with: Entities::ErrorTracking::ProjectSetting
end
desc 'Enable or disable error tracking settings for the project' do
detail 'This feature was introduced in GitLab 12.8.'
success Entities::ErrorTracking::ProjectSetting
end
params do
requires :active, type: Boolean, desc: 'Specifying whether to enable or disable error tracking settings', allow_blank: false
end
patch ':id/error_tracking/settings/' do
authorize! :admin_operations, user_project
setting = user_project.error_tracking_setting
not_found!('Error Tracking Setting') unless setting
update_params = {
error_tracking_setting_attributes: { enabled: params[:active] }
}
result = ::Projects::Operations::UpdateService.new(user_project, current_user, update_params).execute
if result[:status] == :success
present setting, with: Entities::ErrorTracking::ProjectSetting
else
result
end
end
end
end
end
......@@ -8,5 +8,9 @@ FactoryBot.define do
token { 'access_token_123' }
project_name { 'Sentry Project' }
organization_name { 'Sentry Org' }
trait :disabled do
enabled { false }
end
end
end
......@@ -3,11 +3,129 @@
require 'spec_helper'
describe API::ErrorTracking do
describe "GET /projects/:id/error_tracking/settings" do
let(:user) { create(:user) }
let(:setting) { create(:project_error_tracking_setting) }
let(:project) { setting.project }
let(:user) { create(:user) }
let(:setting) { create(:project_error_tracking_setting) }
let(:project) { setting.project }
shared_examples 'returns project settings' do
it 'returns correct project settings' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq(
'active' => setting.reload.enabled,
'project_name' => setting.project_name,
'sentry_external_url' => setting.sentry_external_url,
'api_url' => setting.api_url
)
end
end
shared_examples 'returns 404' do
it 'returns correct project settings' do
subject
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message'])
.to eq('404 Error Tracking Setting Not Found')
end
end
describe "PATCH /projects/:id/error_tracking/settings" do
def make_patch_request(**params)
patch api("/projects/#{project.id}/error_tracking/settings", user), params: params
end
context 'when authenticated as maintainer' do
before do
project.add_maintainer(user)
end
context 'patch settings' do
subject do
make_patch_request(active: false)
end
it_behaves_like 'returns project settings'
it 'returns active is invalid if non boolean' do
make_patch_request(active: "randomstring")
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error'])
.to eq('active is invalid')
end
it 'returns 400 if active is empty' do
make_patch_request(active: '')
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error'])
.to eq('active is empty')
end
end
context 'without a project setting' do
let(:project) { create(:project) }
before do
project.add_maintainer(user)
end
context 'patch settings' do
subject do
make_patch_request(active: true)
end
it_behaves_like 'returns 404'
end
end
end
context 'when authenticated as reporter' do
before do
project.add_reporter(user)
end
it 'returns 403 for update request' do
make_patch_request(active: true)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when authenticated as developer' do
before do
project.add_developer(user)
end
it 'returns 403 for update request' do
make_patch_request(active: true)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when authenticated as non-member' do
it 'returns 404 for update request' do
make_patch_request(active: false)
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when unauthenticated' do
let(:user) { nil }
it 'returns 401 for update request' do
make_patch_request(active: true)
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
describe "GET /projects/:id/error_tracking/settings" do
def make_request
get api("/projects/#{project.id}/error_tracking/settings", user)
end
......@@ -17,16 +135,12 @@ describe API::ErrorTracking do
project.add_maintainer(user)
end
it 'returns project settings' do
make_request
context 'get settings' do
subject do
make_request
end
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq(
'active' => setting.enabled,
'project_name' => setting.project_name,
'sentry_external_url' => setting.sentry_external_url,
'api_url' => setting.api_url
)
it_behaves_like 'returns project settings'
end
end
......@@ -37,12 +151,12 @@ describe API::ErrorTracking do
project.add_maintainer(user)
end
it 'returns 404' do
make_request
context 'get settings' do
subject do
make_request
end
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message'])
.to eq('404 Error Tracking Setting Not Found')
it_behaves_like 'returns 404'
end
end
......@@ -58,6 +172,18 @@ describe API::ErrorTracking do
end
end
context 'when authenticated as developer' do
before do
project.add_developer(user)
end
it 'returns 403' do
make_request
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when authenticated as non-member' do
it 'returns 404' do
make_request
......
......@@ -4,7 +4,7 @@ require 'spec_helper'
describe Projects::Operations::UpdateService do
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project) }
let_it_be(:project, refind: true) { create(:project) }
let(:result) { subject.execute }
......@@ -145,6 +145,48 @@ describe Projects::Operations::UpdateService do
end
end
context 'partial_update' do
let(:params) do
{
error_tracking_setting_attributes: {
enabled: true
}
}
end
context 'with setting' do
before do
create(:project_error_tracking_setting, :disabled, project: project)
end
it 'service succeeds' do
expect(result[:status]).to eq(:success)
end
it 'updates attributes' do
expect { result }
.to change { project.reload.error_tracking_setting.enabled }
.from(false)
.to(true)
end
it 'only updates enabled attribute' do
result
expect(project.error_tracking_setting.previous_changes.keys)
.to contain_exactly('enabled')
end
end
context 'without setting' do
it 'does not create a setting' do
expect(result[:status]).to eq(:error)
expect(project.reload.error_tracking_setting).to be_nil
end
end
end
context 'with masked param token' do
let(:params) do
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment