Commit cbc90565 authored by Robert Schilling's avatar Robert Schilling
Browse files

Do label validation for issues/merge requests API

parent 769ae11a4e24
......@@ -140,7 +140,8 @@ def label_names
def add_labels_by_names(label_names)
label_names.each do |label_name|
label = project.labels.find_or_create_by(title: label_name.strip)
label = project.labels.create_with(
color: Label::DEFAULT_COLOR).find_or_create_by(title: label_name.strip)
self.labels << label
end
end
......
class Label < ActiveRecord::Base
DEFAULT_COLOR = '#82C5FF'
belongs_to :project
has_many :label_links, dependent: :destroy
has_many :issues, through: :label_links, source: :target, source_type: 'Issue'
......
......@@ -157,6 +157,9 @@ Parameters:
- `milestone_id` (optional) - The ID of a milestone to assign issue
- `labels` (optional) - Comma-separated label names for an issue
If the operation is successful, 200 and the newly created issue is returned.
If an error occurs, an error number and a message explaining the reason is returned.
## Edit issue
Updates an existing project issue. This function is also used to mark an issue as closed.
......@@ -176,6 +179,9 @@ Parameters:
- `labels` (optional) - Comma-separated label names for an issue
- `state_event` (optional) - The state event of an issue ('close' to close issue and 'reopen' to reopen it)
If the operation is successful, 200 and the updated issue is returned.
If an error occurs, an error number and a message explaining the reason is returned.
## Delete existing issue (**Deprecated**)
The function is deprecated and returns a `405 Method Not Allowed` error if called. An issue gets now closed and is done by calling `PUT /projects/:id/issues/:issue_id` with parameter `closed` set to 1.
......
......@@ -136,6 +136,9 @@ Parameters:
}
```
If the operation is successful, 200 and the newly created merge request is returned.
If an error occurs, an error number and a message explaining the reason is returned.
## Update MR
Updates an existing merge request. You can change branches, title, or even close the MR.
......@@ -183,15 +186,18 @@ Parameters:
}
```
If the operation is successful, 200 and the updated merge request is returned.
If an error occurs, an error number and a message explaining the reason is returned.
## Accept MR
Merge changes submitted with MR usign this API.
Merge changes submitted with MR using this API.
If merge success you get 200 OK.
If it has some conflicts and can not be merged - you get 405 and error message 'Branch cannot be merged'
If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed'
If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed'
If you dont have permissions to accept this merge request - you get 401
......
......@@ -112,6 +112,21 @@ def attributes_for_keys(keys)
ActionController::Parameters.new(attrs).permit!
end
# Helper method for validating all labels against its names
def validate_label_params(params)
if params[:labels].present?
params[:labels].split(',').each do |label_name|
label = user_project.labels.create_with(
color: Label::DEFAULT_COLOR).find_or_initialize_by(
title: label_name.strip)
if label.invalid?
return true
end
end
end
false
end
# error helpers
def forbidden!
......
......@@ -51,12 +51,18 @@ class Issues < Grape::API
required_attributes! [:title]
attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id]
# Validate label names in advance
if validate_label_params(params)
return render_api_error!('Label names invalid', 405)
end
issue = ::Issues::CreateService.new(user_project, current_user, attrs).execute
if issue.valid?
# Find or create labels and attach to issue
# Find or create labels and attach to issue. Labels are valid because
# we already checked its name, so there can't be an error here
if params[:labels].present?
issue.add_labels_by_names(params[:labels].split(","))
issue.add_labels_by_names(params[:labels].split(','))
end
present issue, with: Entities::Issue
......@@ -83,12 +89,19 @@ class Issues < Grape::API
authorize! :modify_issue, issue
attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :state_event]
# Validate label names in advance
if validate_label_params(params)
return render_api_error!('Label names invalid', 405)
end
issue = ::Issues::UpdateService.new(user_project, current_user, attrs).execute(issue)
if issue.valid?
# Find or create labels and attach to issue
# Find or create labels and attach to issue. Labels are valid because
# we already checked its name, so there can't be an error here
if params[:labels].present?
issue.add_labels_by_names(params[:labels].split(","))
# Create and add labels to the new created issue
issue.add_labels_by_names(params[:labels].split(','))
end
present issue, with: Entities::Issue
......
......@@ -76,6 +76,12 @@ def handle_merge_request_errors!(errors)
authorize! :write_merge_request, user_project
required_attributes! [:source_branch, :target_branch, :title]
attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description]
# Validate label names in advance
if validate_label_params(params)
return render_api_error!('Label names invalid', 405)
end
merge_request = ::MergeRequests::CreateService.new(user_project, current_user, attrs).execute
if merge_request.valid?
......@@ -109,6 +115,12 @@ def handle_merge_request_errors!(errors)
attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event, :description]
merge_request = user_project.merge_requests.find(params[:merge_request_id])
authorize! :modify_merge_request, merge_request
# Validate label names in advance
if validate_label_params(params)
return render_api_error!('Label names invalid', 405)
end
merge_request = ::MergeRequests::UpdateService.new(user_project, current_user, attrs).execute(merge_request)
if merge_request.valid?
......
......@@ -5,6 +5,10 @@
let(:user) { create(:user) }
let!(:project) { create(:project, namespace: user.namespace ) }
let!(:issue) { create(:issue, author: user, assignee: user, project: project) }
let!(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project)
end
before { project.team << [user, :reporter] }
describe "GET /issues" do
......@@ -68,6 +72,14 @@
post api("/projects/#{project.id}/issues", user), labels: 'label, label2'
response.status.should == 400
end
it 'should return 405 on invalid label names' do
post api("/projects/#{project.id}/issues", user),
title: 'new issue',
labels: 'label, ?'
response.status.should == 405
json_response['message'].should == 'Label names invalid'
end
end
describe "PUT /projects/:id/issues/:issue_id to update only title" do
......@@ -84,6 +96,14 @@
title: 'updated title'
response.status.should == 404
end
it 'should return 405 on invalid label names' do
put api("/projects/#{project.id}/issues/#{issue.id}", user),
title: 'updated title',
labels: 'label, ?'
response.status.should == 405
json_response['message'].should == 'Label names invalid'
end
end
describe "PUT /projects/:id/issues/:issue_id to update state and label" do
......
......@@ -78,9 +78,14 @@
context 'between branches projects' do
it "should return merge_request" do
post api("/projects/#{project.id}/merge_requests", user),
title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user
title: 'Test merge_request',
source_branch: 'stable',
target_branch: 'master',
author: user,
labels: 'label, label2'
response.status.should == 201
json_response['title'].should == 'Test merge_request'
json_response['labels'].should == ['label', 'label2']
end
it "should return 422 when source_branch equals target_branch" do
......@@ -106,6 +111,17 @@
target_branch: 'master', source_branch: 'stable'
response.status.should == 400
end
it 'should return 405 on invalid label names' do
post api("/projects/#{project.id}/merge_requests", user),
title: 'Test merge_request',
source_branch: 'stable',
target_branch: 'master',
author: user,
labels: 'label, ?'
response.status.should == 405
json_response['message'].should == 'Label names invalid'
end
end
context 'forked projects' do
......@@ -235,6 +251,15 @@
response.status.should == 200
json_response['target_branch'].should == 'wiki'
end
it 'should return 405 on invalid label names' do
put api("/projects/#{project.id}/merge_request/#{merge_request.id}",
user),
title: 'new issue',
labels: 'label, ?'
response.status.should == 405
json_response['message'].should == 'Label names invalid'
end
end
describe "POST /projects/:id/merge_request/:merge_request_id/comments" 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