diff --git a/changelogs/unreleased/41476-enable-project-milestons-deletion-via-api.yml b/changelogs/unreleased/41476-enable-project-milestons-deletion-via-api.yml new file mode 100644 index 00000000000..bb5c1fdf082 --- /dev/null +++ b/changelogs/unreleased/41476-enable-project-milestons-deletion-via-api.yml @@ -0,0 +1,5 @@ +--- +title: Enables Project Milestone Deletion via the API +merge_request: 16478 +author: Jacopo Beschi @jacopo-beschi +type: added diff --git a/doc/api/milestones.md b/doc/api/milestones.md index 84930f0bdc9..d35e940d7b1 100644 --- a/doc/api/milestones.md +++ b/doc/api/milestones.md @@ -93,6 +93,19 @@ Parameters: - `start_date` (optional) - The start date of the milestone - `state_event` (optional) - The state event of the milestone (close|activate) +## Delete project milestone + +Only for user with developer access to the project. + +``` +DELETE /projects/:id/milestones/:milestone_id +``` + +Parameters: + +- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user +- `milestone_id` (required) - The ID of the project's milestone + ## Get all issues assigned to a single milestone Gets all issues assigned to a single project milestone. diff --git a/lib/api/project_milestones.rb b/lib/api/project_milestones.rb index 0cb209a02d0..306dc0e63d7 100644 --- a/lib/api/project_milestones.rb +++ b/lib/api/project_milestones.rb @@ -60,6 +60,15 @@ module API update_milestone_for(user_project) end + desc 'Remove a project milestone' + delete ":id/milestones/:milestone_id" do + authorize! :admin_milestone, user_project + + user_project.milestones.find(params[:milestone_id]).destroy + + status(204) + end + desc 'Get all issues for a single project milestone' do success Entities::IssueBasic end diff --git a/spec/requests/api/project_milestones_spec.rb b/spec/requests/api/project_milestones_spec.rb index 08ea7314bb3..6c05c166bd6 100644 --- a/spec/requests/api/project_milestones_spec.rb +++ b/spec/requests/api/project_milestones_spec.rb @@ -14,6 +14,46 @@ describe API::ProjectMilestones do let(:route) { "/projects/#{project.id}/milestones" } end + describe 'DELETE /projects/:id/milestones/:milestone_id' do + let(:guest) { create(:user) } + let(:reporter) { create(:user) } + + before do + project.add_reporter(reporter) + end + + it 'returns 404 response when the project does not exists' do + delete api("/projects/999/milestones/#{milestone.id}", user) + + expect(response).to have_gitlab_http_status(404) + end + + it 'returns 404 response when the milestone does not exists' do + delete api("/projects/#{project.id}/milestones/999", user) + + expect(response).to have_gitlab_http_status(404) + end + + it "returns 404 from guest user deleting a milestone" do + delete api("/projects/#{project.id}/milestones/#{milestone.id}", guest) + + expect(response).to have_gitlab_http_status(404) + end + + it "rejects a member with reporter access from deleting a milestone" do + delete api("/projects/#{project.id}/milestones/#{milestone.id}", reporter) + + expect(response).to have_gitlab_http_status(403) + end + + it 'deletes the milestone when the user has developer access to the project' do + delete api("/projects/#{project.id}/milestones/#{milestone.id}", user) + + expect(project.milestones.find_by_id(milestone.id)).to be_nil + expect(response).to have_gitlab_http_status(204) + end + end + describe 'PUT /projects/:id/milestones/:milestone_id to test observer on close' do it 'creates an activity event when an milestone is closed' do expect(Event).to receive(:create!)