summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/routes.rb1
-rw-r--r--doc/api/notes.md10
-rw-r--r--doc/api/projects.md7
-rw-r--r--lib/api.rb13
-rw-r--r--lib/api/merge_requests.rb22
-rw-r--r--lib/api/milestones.rb16
-rw-r--r--lib/api/notes.rb2
-rw-r--r--lib/api/projects.rb6
-rw-r--r--spec/requests/api/merge_requests_spec.rb40
-rw-r--r--spec/requests/api/milestones_spec.rb24
-rw-r--r--spec/requests/api/notes_spec.rb30
-rw-r--r--spec/requests/api/projects_spec.rb17
12 files changed, 180 insertions, 8 deletions
diff --git a/config/routes.rb b/config/routes.rb
index d6432b86007..ddf284f1fe5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -8,6 +8,7 @@ Gitlab::Application.routes.draw do
# API
require 'api'
+ Gitlab::API.logger Rails.logger
mount Gitlab::API => '/api'
constraint = lambda { |request| request.env["warden"].authenticate? and request.env['warden'].user.admin? }
diff --git a/doc/api/notes.md b/doc/api/notes.md
index a4ba2826076..eef4b63fcaf 100644
--- a/doc/api/notes.md
+++ b/doc/api/notes.md
@@ -89,7 +89,7 @@ Parameters:
Get an issue note.
```
-GET /projects/:id/issues/:issue_id/:notes/:note_id
+GET /projects/:id/issues/:issue_id/notes/:note_id
```
Parameters:
@@ -103,7 +103,7 @@ Parameters:
Get a snippet note.
```
-GET /projects/:id/issues/:snippet_id/:notes/:note_id
+GET /projects/:id/issues/:snippet_id/notes/:note_id
```
Parameters:
@@ -127,7 +127,7 @@ Parameters:
+ `id` (required) - The ID of a project
+ `body` (required) - The content of a note
-Will return created note with status `201 Created` on success, or `404 Not found` on fail.
+Will return created note with status `201 Created` on success, `400 Bad Request` if the body attribute is missing or `404 Not found` on fail.
### New issue note
@@ -144,7 +144,7 @@ Parameters:
+ `issue_id` (required) - The ID of an issue
+ `body` (required) - The content of a note
-Will return created note with status `201 Created` on success, or `404 Not found` on fail.
+Will return created note with status `201 Created` on success, `400 Bad Request` if the body attribute is missing or `404 Not found` on fail.
### New snippet note
@@ -160,4 +160,4 @@ Parameters:
+ `snippet_id` (required) - The ID of an snippet
+ `body` (required) - The content of a note
-Will return created note with status `201 Created` on success, or `404 Not found` on fail.
+Will return created note with status `201 Created` on success, `400 Bad Request` if the body attribute is missing or `404 Not found` on fail.
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 82bb0c0d561..03731427703 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -197,7 +197,10 @@ Parameters:
+ `id` (required) - The ID of a project
+ `user_id` (required) - The ID of a team member
-Status code `200` will be returned on success.
+Status code `200 OK` will be returned on success. This method is idempotent and call be called multiple
+times with the same parameters. Revoking team membership for a user who is not currently a team member is
+considered success. Please note that the returned JSON currently differs slightly. Thus you should not
+rely on the returned JSON structure.
## List project hooks
@@ -221,7 +224,7 @@ Get hook for project
GET /projects/:id/hooks/:hook_id
```
-Parameters:
+Parameters:ยง
+ `id` (required) - The ID of a project
+ `hook_id` (required) - The ID of a project hook
diff --git a/lib/api.rb b/lib/api.rb
index d9dce7c70cc..ffd980ca7e0 100644
--- a/lib/api.rb
+++ b/lib/api.rb
@@ -8,6 +8,19 @@ module Gitlab
rack_response({'message' => '404 Not found'}.to_json, 404)
end
+ rescue_from :all do |exception|
+ # lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60
+ # why is this not wrapped in something reusable?
+ trace = exception.backtrace
+
+ message = "\n#{exception.class} (#{exception.message}):\n"
+ message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
+ message << " " << trace.join("\n ")
+
+ API.logger.add Logger::FATAL, message
+ rack_response({'message' => '500 Internal Server Error'}, 500)
+ end
+
format :json
error_format :json
helpers APIHelpers
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 470cd1e1c2d..a0ca3026acb 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -5,6 +5,23 @@ module Gitlab
resource :projects do
+ helpers do
+ # If an error occurred this helper method provides an appropriate status code
+ #
+ # Parameters:
+ # merge_request_errors (required) - The errors collection of MR
+ #
+ def handle_merge_request_error(merge_request_errors)
+ if merge_request_errors[:target_branch].any?
+ error!(merge_request_errors[:target_branch], 400)
+ elsif merge_request_errors[:source_branch].any?
+ error!(merge_request_errors[:source_branch], 400)
+ elsif merge_request_errors[:base].any?
+ error!(merge_request_errors[:base], 422)
+ end
+ end
+ end
+
# List merge requests
#
# Parameters:
@@ -60,6 +77,7 @@ module Gitlab
merge_request.reload_code
present merge_request, with: Entities::MergeRequest
else
+ handle_merge_request_error(merge_request.errors)
not_found!
end
end
@@ -88,6 +106,7 @@ module Gitlab
merge_request.mark_as_unchecked
present merge_request, with: Entities::MergeRequest
else
+ handle_merge_request_error(merge_request.errors)
not_found!
end
end
@@ -109,6 +128,9 @@ module Gitlab
if note.save
present note, with: Entities::MRNote
else
+ if note.errors[:note].any?
+ error!(note.errors[:note], 400)
+ end
not_found!
end
end
diff --git a/lib/api/milestones.rb b/lib/api/milestones.rb
index 6aca9d01b09..1f7d0876120 100644
--- a/lib/api/milestones.rb
+++ b/lib/api/milestones.rb
@@ -4,6 +4,20 @@ module Gitlab
before { authenticate! }
resource :projects do
+
+ helpers do
+ # If an error occurs this helper method handles error codes for a given milestone
+ #
+ # Parameters:
+ # milestone_errors (required) - The erros collection of a milestone
+ #
+ def handle_milestone_errors(milestone_errors)
+ if milestone_errors[:title].any?
+ error!(milestone_errors[:title], 400)
+ end
+ end
+ end
+
# Get a list of project milestones
#
# Parameters:
@@ -47,6 +61,7 @@ module Gitlab
if @milestone.save
present @milestone, with: Entities::Milestone
else
+ handle_milestone_errors(@milestone.errors)
not_found!
end
end
@@ -70,6 +85,7 @@ module Gitlab
if @milestone.update_attributes attrs
present @milestone, with: Entities::Milestone
else
+ handle_milestone_errors(@milestone.errors)
not_found!
end
end
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index 70344d6e381..47dead9dfae 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -43,6 +43,8 @@ module Gitlab
if @note.save
present @note, with: Entities::Note
else
+ # :note is exposed as :body, but :note is set on error
+ error!(@note.errors[:note], 400) if @note.errors[:note].any?
not_found!
end
end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index a16243aa822..47ab4e1aab0 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -132,7 +132,11 @@ module Gitlab
delete ":id/members/:user_id" do
authorize! :admin_project, user_project
users_project = user_project.users_projects.find_by_user_id params[:user_id]
- users_project.destroy
+ unless users_project.nil?
+ users_project.destroy
+ else
+ {:message => "Access revoked", :id => params[:user_id].to_i}
+ end
end
# Get project hooks
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 5da54154a81..4e7a84dfb47 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -41,6 +41,24 @@ describe Gitlab::API do
response.status.should == 201
json_response['title'].should == 'Test merge_request'
end
+
+ it "should return 422 when source_branch equals target_branch" do
+ post api("/projects/#{project.id}/merge_requests", user),
+ title: "Test merge_request", source_branch: "master", target_branch: "master", author: user
+ response.status.should == 422
+ end
+
+ it "should return 400 when source_branch is missing" do
+ post api("/projects/#{project.id}/merge_requests", user),
+ title: "Test merge_request", target_branch: "master", author: user
+ response.status.should == 400
+ end
+
+ it "should return 400 when target_branch is missing" do
+ post api("/projects/#{project.id}/merge_requests", user),
+ title: "Test merge_request", source_branch: "stable", author: user
+ response.status.should == 400
+ end
end
describe "PUT /projects/:id/merge_request/:merge_request_id" do
@@ -49,6 +67,18 @@ describe Gitlab::API do
response.status.should == 200
json_response['title'].should == 'New title'
end
+
+ it "should return 422 when source_branch and target_branch are renamed the same" do
+ put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user),
+ source_branch: "master", target_branch: "master"
+ response.status.should == 422
+ end
+
+ it "should return merge_request with renamed target_branch" do
+ put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), target_branch: "test"
+ response.status.should == 200
+ json_response['target_branch'].should == 'test'
+ end
end
describe "POST /projects/:id/merge_request/:merge_request_id/comments" do
@@ -57,6 +87,16 @@ describe Gitlab::API do
response.status.should == 201
json_response['note'].should == 'My comment'
end
+
+ it "should return 400 if note is missing" do
+ post api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user)
+ response.status.should == 400
+ end
+
+ it "should return 404 if note is attached to non existent merge request" do
+ post api("/projects/#{project.id}/merge_request/111/comments", user), note: "My comment"
+ response.status.should == 404
+ end
end
end
diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb
index 80696671462..3cab63557a9 100644
--- a/spec/requests/api/milestones_spec.rb
+++ b/spec/requests/api/milestones_spec.rb
@@ -24,6 +24,11 @@ describe Gitlab::API do
response.status.should == 200
json_response['title'].should == milestone.title
end
+
+ it "should return a 404 error if milestone id not found" do
+ get api("/projects/#{project.id}/milestones/1234", user)
+ response.status.should == 404
+ end
end
describe "POST /projects/:id/milestones" do
@@ -34,6 +39,19 @@ describe Gitlab::API do
json_response['title'].should == 'new milestone'
json_response['description'].should be_nil
end
+
+ it "should create a new project milestone with description and due date" do
+ post api("/projects/#{project.id}/milestones", user),
+ title: 'new milestone', description: 'release', due_date: '2013-03-02'
+ response.status.should == 201
+ json_response['description'].should == 'release'
+ json_response['due_date'].should == '2013-03-02'
+ end
+
+ it "should return a 400 error if title is missing" do
+ post api("/projects/#{project.id}/milestones", user)
+ response.status.should == 400
+ end
end
describe "PUT /projects/:id/milestones/:milestone_id" do
@@ -43,5 +61,11 @@ describe Gitlab::API do
response.status.should == 200
json_response['title'].should == 'updated title'
end
+
+ it "should return a 404 error if milestone is not found" do
+ put api("/projects/#{project.id}/milestones/1234", user),
+ title: 'updated title'
+ response.status.should == 404
+ end
end
end
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index ee99d85df4d..d382d7d9294 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -38,6 +38,11 @@ describe Gitlab::API do
response.status.should == 200
json_response['body'].should == wall_note.note
end
+
+ it "should return a 404 error if note not found" do
+ get api("/projects/#{project.id}/notes/123", user)
+ response.status.should == 404
+ end
end
describe "POST /projects/:id/notes" do
@@ -46,6 +51,11 @@ describe Gitlab::API do
response.status.should == 201
json_response['body'].should == 'hi!'
end
+
+ it "should return a 400 error if body is missing" do
+ post api("/projects/#{project.id}/notes", user)
+ response.status.should == 400
+ end
end
describe "GET /projects/:id/noteable/:noteable_id/notes" do
@@ -56,6 +66,11 @@ describe Gitlab::API do
json_response.should be_an Array
json_response.first['body'].should == issue_note.note
end
+
+ it "should return a 404 error when issue id not found" do
+ get api("/projects/#{project.id}/issues/123/notes", user)
+ response.status.should == 404
+ end
end
context "when noteable is a Snippet" do
@@ -65,6 +80,11 @@ describe Gitlab::API do
json_response.should be_an Array
json_response.first['body'].should == snippet_note.note
end
+
+ it "should return a 404 error when snippet id not found" do
+ get api("/projects/#{project.id}/snippets/42/notes", user)
+ response.status.should == 404
+ end
end
context "when noteable is a Merge Request" do
@@ -84,6 +104,11 @@ describe Gitlab::API do
response.status.should == 200
json_response['body'].should == issue_note.note
end
+
+ it "should return a 404 error if issue note not found" do
+ get api("/projects/#{project.id}/issues/#{issue.id}/notes/123", user)
+ response.status.should == 404
+ end
end
context "when noteable is a Snippet" do
@@ -92,6 +117,11 @@ describe Gitlab::API do
response.status.should == 200
json_response['body'].should == snippet_note.note
end
+
+ it "should return a 404 error if snippet note not found" do
+ get api("/projects/#{project.id}/snippets/#{snippet.id}/notes/123", user)
+ response.status.should == 404
+ end
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index d932fd9e74d..2682629e7db 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -89,6 +89,12 @@ describe Gitlab::API do
response.status.should == 404
json_response['message'].should == '404 Not Found'
end
+
+ it "should return a 404 error if user is not a member" do
+ other_user = create(:user)
+ get api("/projects/#{project.id}", other_user)
+ response.status.should == 404
+ end
end
describe "GET /projects/:id/repository/branches" do
@@ -190,6 +196,17 @@ describe Gitlab::API do
end
end
+ describe "DELETE /projects/:id/members/:user_id" do
+ it "should return 200 OK when the user was not member" do
+ expect {
+ delete api("/projects/#{project.id}/members/1000000", user)
+ }.to change { UsersProject.count }.by(0)
+ response.status.should == 200
+ json_response['message'].should == "Access revoked"
+ json_response['id'].should == 1000000
+ end
+ end
+
describe "GET /projects/:id/hooks" do
it "should return project hooks" do
get api("/projects/#{project.id}/hooks", user)