Commit 818caf0b authored by Sebastian Ziebell's avatar Sebastian Ziebell

API: refined status code handling when adding or updating a project member

When a user is added to a project that is already a member of, a status code 201 is now returned to
signal an idempotent operation. If something fails then instead of returning error code 404 different
more specific error codes are returned. Status code 400 (Bad request) is returned when a required
attribute, e.g. `access_level` is not given or 422 if there is a semantic error, e.g. should
the `access_level` have an unsupported value.

Specs are added to check these status codes.
parent 8045a81b
...@@ -89,15 +89,26 @@ module Gitlab ...@@ -89,15 +89,26 @@ module Gitlab
# POST /projects/:id/members # POST /projects/:id/members
post ":id/members" do post ":id/members" do
authorize! :admin_project, user_project authorize! :admin_project, user_project
users_project = user_project.users_projects.new(
error!("User id not given", 400) if !params.has_key? :user_id
error!("Access level not given", 400) if !params.has_key? :access_level
# either the user is already a team member or a new one
team_member = user_project.team_member_by_id(params[:user_id])
if team_member.nil?
team_member = user_project.users_projects.new(
user_id: params[:user_id], user_id: params[:user_id],
project_access: params[:access_level] project_access: params[:access_level]
) )
end
if users_project.save if team_member.save
@member = users_project.user @member = team_member.user
present @member, with: Entities::ProjectMember, project: user_project present @member, with: Entities::ProjectMember, project: user_project
else else
if team_member.errors[:project_access].any?
error!(team_member.errors[:project_access], 422)
end
not_found! not_found!
end end
end end
...@@ -112,12 +123,18 @@ module Gitlab ...@@ -112,12 +123,18 @@ module Gitlab
# PUT /projects/:id/members/:user_id # PUT /projects/:id/members/:user_id
put ":id/members/:user_id" do put ":id/members/:user_id" do
authorize! :admin_project, user_project authorize! :admin_project, user_project
users_project = user_project.users_projects.find_by_user_id params[:user_id]
if users_project.update_attributes(project_access: params[:access_level]) team_member = user_project.users_projects.find_by_user_id(params[:user_id])
@member = users_project.user error!("Access level not given", 400) if !params.has_key? :access_level
error!("User can not be found", 404) if team_member.nil?
if team_member.update_attributes(project_access: params[:access_level])
@member = team_member.user
present @member, with: Entities::ProjectMember, project: user_project present @member, with: Entities::ProjectMember, project: user_project
else else
if team_member.errors[:project_access].any?
error!(team_member.errors[:project_access], 422)
end
not_found! not_found!
end end
end end
......
...@@ -177,6 +177,34 @@ describe Gitlab::API do ...@@ -177,6 +177,34 @@ describe Gitlab::API do
json_response['email'].should == user2.email json_response['email'].should == user2.email
json_response['access_level'].should == UsersProject::DEVELOPER json_response['access_level'].should == UsersProject::DEVELOPER
end end
it "should return a 201 status if user is already project member" do
post api("/projects/#{project.id}/members", user), user_id: user2.id,
access_level: UsersProject::DEVELOPER
expect {
post api("/projects/#{project.id}/members", user), user_id: user2.id,
access_level: UsersProject::DEVELOPER
}.not_to change { UsersProject.count }.by(1)
response.status.should == 201
json_response['email'].should == user2.email
json_response['access_level'].should == UsersProject::DEVELOPER
end
it "should return a 400 error when user id is not given" do
post api("/projects/#{project.id}/members", user), access_level: UsersProject::MASTER
response.status.should == 400
end
it "should return a 400 error when access level is not given" do
post api("/projects/#{project.id}/members", user), user_id: user2.id
response.status.should == 400
end
it "should return a 422 error when access level is not known" do
post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: 1234
response.status.should == 422
end
end end
describe "PUT /projects/:id/members/:user_id" do describe "PUT /projects/:id/members/:user_id" do
...@@ -186,6 +214,21 @@ describe Gitlab::API do ...@@ -186,6 +214,21 @@ describe Gitlab::API do
json_response['email'].should == user3.email json_response['email'].should == user3.email
json_response['access_level'].should == UsersProject::MASTER json_response['access_level'].should == UsersProject::MASTER
end end
it "should return a 404 error if user_id is not found" do
put api("/projects/#{project.id}/members/1234", user), access_level: UsersProject::MASTER
response.status.should == 404
end
it "should return a 400 error when access level is not given" do
put api("/projects/#{project.id}/members/#{user3.id}", user)
response.status.should == 400
end
it "should return a 422 error when access level is not known" do
put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: 123
response.status.should == 422
end
end end
describe "DELETE /projects/:id/members/:user_id" do describe "DELETE /projects/:id/members/:user_id" 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