Commit a82a85ec authored by Peter Leitzen's avatar Peter Leitzen

Merge branch 'mwaw/214581-delete-star-metrics-dashboard-endpoint' into 'master'

#214581 Delete star from metrics dashboard endpoint

See merge request gitlab-org/gitlab!31892
parents 35baa114 72dafdbf
...@@ -46,11 +46,15 @@ module MetricsDashboard ...@@ -46,11 +46,15 @@ module MetricsDashboard
dashboard[:can_edit] = project_dashboard ? can_edit?(dashboard) : false dashboard[:can_edit] = project_dashboard ? can_edit?(dashboard) : false
dashboard[:project_blob_path] = project_dashboard ? dashboard_project_blob_path(dashboard) : nil dashboard[:project_blob_path] = project_dashboard ? dashboard_project_blob_path(dashboard) : nil
dashboard[:starred] = starred_dashboards.include?(dashboard[:path]) dashboard[:starred] = starred_dashboards.include?(dashboard[:path])
dashboard[:user_starred_path] = nil # placeholder attribute until API endpoint will be merged https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31316 dashboard[:user_starred_path] = project_for_dashboard ? user_starred_path(project_for_dashboard, dashboard[:path]) : nil
dashboard dashboard
end end
def user_starred_path(project, path)
expose_path(api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: path }))
end
def dashboard_project_blob_path(dashboard) def dashboard_project_blob_path(dashboard)
project_blob_path(project_for_dashboard, File.join(project_for_dashboard.default_branch, dashboard.fetch(:path, ""))) project_blob_path(project_for_dashboard, File.join(project_for_dashboard.default_branch, dashboard.fetch(:path, "")))
end end
......
---
title: New API endpoint for removing stars from metrics dashboards
merge_request: 31892
author:
type: added
...@@ -32,3 +32,30 @@ Example Response: ...@@ -32,3 +32,30 @@ Example Response:
"project_id": 20 "project_id": 20
} }
``` ```
## Remove a star from a dashboard
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31892) in GitLab 13.0.
```plaintext
DELETE /projects/:id/metrics/user_starred_dashboards
```
Parameters:
| Attribute | Type | Required | Description |
|:---------------|:---------------|:---------|:-----------------------------------------------------------------------------|
| `dashboard_path` | string | no | URL-encoded path to file defining the dashboard which should no longer be marked as favorite. When not supplied all dashboards within given projects will be removed from favorites. |
```shell
curl --request DELETE --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/projects/20/metrics/user_starred_dashboards \
--data-urlencode "dashboard_path=config/prometheus/dashboards/common_metrics.yml"
```
Example Response:
```json
{
"deleted_rows": 1
}
```
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
module API module API
module Metrics module Metrics
class UserStarredDashboards < Grape::API class UserStarredDashboards < Grape::API
resource :projects do
desc 'Marks selected metrics dashboard as starred' do desc 'Marks selected metrics dashboard as starred' do
success Entities::Metrics::UserStarredDashboard success Entities::Metrics::UserStarredDashboard
end end
...@@ -12,7 +13,6 @@ module API ...@@ -12,7 +13,6 @@ module API
desc: 'Url encoded path to a file defining the dashboard to which the star should be added' desc: 'Url encoded path to a file defining the dashboard to which the star should be added'
end end
resource :projects do
post ':id/metrics/user_starred_dashboards' do post ':id/metrics/user_starred_dashboards' do
result = ::Metrics::UsersStarredDashboards::CreateService.new(current_user, user_project, params[:dashboard_path]).execute result = ::Metrics::UsersStarredDashboards::CreateService.new(current_user, user_project, params[:dashboard_path]).execute
...@@ -22,6 +22,24 @@ module API ...@@ -22,6 +22,24 @@ module API
error!({ errors: result.message }, 400) error!({ errors: result.message }, 400)
end end
end end
desc 'Remove star from selected metrics dashboard'
params do
optional :dashboard_path, type: String, allow_blank: false, coerce_with: ->(val) { CGI.unescape(val) },
desc: 'Url encoded path to a file defining the dashboard from which the star should be removed'
end
delete ':id/metrics/user_starred_dashboards' do
result = ::Metrics::UsersStarredDashboards::DeleteService.new(current_user, user_project, params[:dashboard_path]).execute
if result.success?
status :ok
result.payload
else
status :bad_request
end
end
end end
end end
end end
......
...@@ -134,10 +134,10 @@ describe MetricsDashboard do ...@@ -134,10 +134,10 @@ describe MetricsDashboard do
it 'adds starred dashboard information and sorts the list' do it 'adds starred dashboard information and sorts the list' do
all_dashboards = json_response['all_dashboards'].map { |dashboard| dashboard.slice('display_name', 'starred', 'user_starred_path') } all_dashboards = json_response['all_dashboards'].map { |dashboard| dashboard.slice('display_name', 'starred', 'user_starred_path') }
expected_response = [ expected_response = [
{ "display_name" => "Default", "starred" => false, 'user_starred_path' => nil }, { "display_name" => "Default", "starred" => false, 'user_starred_path' => api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: 'config/prometheus/common_metrics.yml' }) },
{ "display_name" => "anomaly.yml", "starred" => false, 'user_starred_path' => nil }, { "display_name" => "anomaly.yml", "starred" => false, 'user_starred_path' => api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: '.gitlab/dashboards/anomaly.yml' }) },
{ "display_name" => "errors.yml", "starred" => true, 'user_starred_path' => nil }, { "display_name" => "errors.yml", "starred" => true, 'user_starred_path' => api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: '.gitlab/dashboards/errors.yml' }) },
{ "display_name" => "test.yml", "starred" => true, 'user_starred_path' => nil } { "display_name" => "test.yml", "starred" => true, 'user_starred_path' => api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: '.gitlab/dashboards/test.yml' }) }
] ]
expect(all_dashboards).to eql expected_response expect(all_dashboards).to eql expected_response
......
...@@ -4,20 +4,17 @@ require 'spec_helper' ...@@ -4,20 +4,17 @@ require 'spec_helper'
describe API::Metrics::UserStarredDashboards do describe API::Metrics::UserStarredDashboards do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let!(:project) { create(:project, :private, :repository, :custom_repo, namespace: user.namespace, files: { dashboard => dashboard_yml }) } let_it_be(:dashboard_yml) { fixture_file('lib/gitlab/metrics/dashboard/sample_dashboard.yml') }
let(:dashboard_yml) { fixture_file('lib/gitlab/metrics/dashboard/sample_dashboard.yml') } let_it_be(:dashboard) { '.gitlab/dashboards/find&seek.yml' }
let(:dashboard) { '.gitlab/dashboards/find&seek.yml' } let_it_be(:project) { create(:project, :private, :repository, :custom_repo, namespace: user.namespace, files: { dashboard => dashboard_yml }) }
let(:url) { "/projects/#{project.id}/metrics/user_starred_dashboards" }
let(:params) do let(:params) do
{ {
user: user,
project: project,
dashboard_path: CGI.escape(dashboard) dashboard_path: CGI.escape(dashboard)
} }
end end
describe 'POST /projects/:id/metrics/user_starred_dashboards' do describe 'POST /projects/:id/metrics/user_starred_dashboards' do
let(:url) { "/projects/#{project.id}/metrics/user_starred_dashboards" }
before do before do
project.add_reporter(user) project.add_reporter(user)
end end
...@@ -25,7 +22,7 @@ describe API::Metrics::UserStarredDashboards do ...@@ -25,7 +22,7 @@ describe API::Metrics::UserStarredDashboards do
context 'with correct permissions' do context 'with correct permissions' do
context 'with valid parameters' do context 'with valid parameters' do
context 'dashboard_path as url param url escaped' do context 'dashboard_path as url param url escaped' do
it 'creates a new annotation', :aggregate_failures do it 'creates a new user starred metrics dashboard', :aggregate_failures do
post api(url, user), params: params post api(url, user), params: params
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:created)
...@@ -38,13 +35,11 @@ describe API::Metrics::UserStarredDashboards do ...@@ -38,13 +35,11 @@ describe API::Metrics::UserStarredDashboards do
context 'dashboard_path in request body unescaped' do context 'dashboard_path in request body unescaped' do
let(:params) do let(:params) do
{ {
user: user,
project: project,
dashboard_path: dashboard dashboard_path: dashboard
} }
end end
it 'creates a new annotation', :aggregate_failures do it 'creates a new user starred metrics dashboard', :aggregate_failures do
post api(url, user), params: params post api(url, user), params: params
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:created)
...@@ -89,4 +84,81 @@ describe API::Metrics::UserStarredDashboards do ...@@ -89,4 +84,81 @@ describe API::Metrics::UserStarredDashboards do
end end
end end
end end
describe 'DELETE /projects/:id/metrics/user_starred_dashboards' do
let_it_be(:user_starred_dashboard_1) { create(:metrics_users_starred_dashboard, user: user, project: project, dashboard_path: dashboard) }
let_it_be(:user_starred_dashboard_2) { create(:metrics_users_starred_dashboard, user: user, project: project) }
let_it_be(:other_user_starred_dashboard) { create(:metrics_users_starred_dashboard, project: project) }
let_it_be(:other_project_starred_dashboard) { create(:metrics_users_starred_dashboard, user: user) }
before do
project.add_reporter(user)
end
context 'with correct permissions' do
context 'with valid parameters' do
context 'dashboard_path as url param url escaped' do
it 'deletes given user starred metrics dashboard', :aggregate_failures do
delete api(url, user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['deleted_rows']).to eq(1)
expect(::Metrics::UsersStarredDashboard.all.pluck(:dashboard_path)).not_to include(dashboard)
end
end
context 'dashboard_path in request body unescaped' do
let(:params) do
{
dashboard_path: dashboard
}
end
it 'deletes given user starred metrics dashboard', :aggregate_failures do
delete api(url, user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['deleted_rows']).to eq(1)
expect(::Metrics::UsersStarredDashboard.all.pluck(:dashboard_path)).not_to include(dashboard)
end
end
context 'dashboard_path has not been specified' do
it 'deletes all starred dashboards for that user within given project', :aggregate_failures do
delete api(url, user), params: {}
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['deleted_rows']).to eq(2)
expect(::Metrics::UsersStarredDashboard.all).to contain_exactly(other_user_starred_dashboard, other_project_starred_dashboard)
end
end
end
context 'with invalid parameters' do
context 'user is missing' do
it 'returns 404 not found' do
post api(url, nil), params: params
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'project is missing' do
it 'returns 404 not found' do
post api("/projects/#{project.id + 1}/user_starred_dashboards", user), params: params
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
context 'without correct permissions' do
it 'returns 404 not found' do
post api(url, create(:user)), params: params
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end end
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