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.
This commit is contained in:
parent
8045a81bcf
commit
818caf0b5d
2 changed files with 69 additions and 9 deletions
|
@ -89,15 +89,26 @@ module Gitlab
|
|||
# POST /projects/:id/members
|
||||
post ":id/members" do
|
||||
authorize! :admin_project, user_project
|
||||
users_project = user_project.users_projects.new(
|
||||
user_id: params[:user_id],
|
||||
project_access: params[:access_level]
|
||||
)
|
||||
|
||||
if users_project.save
|
||||
@member = users_project.user
|
||||
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],
|
||||
project_access: params[:access_level]
|
||||
)
|
||||
end
|
||||
|
||||
if team_member.save
|
||||
@member = team_member.user
|
||||
present @member, with: Entities::ProjectMember, project: user_project
|
||||
else
|
||||
if team_member.errors[:project_access].any?
|
||||
error!(team_member.errors[:project_access], 422)
|
||||
end
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
@ -112,12 +123,18 @@ module Gitlab
|
|||
# PUT /projects/:id/members/:user_id
|
||||
put ":id/members/:user_id" do
|
||||
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])
|
||||
@member = users_project.user
|
||||
team_member = user_project.users_projects.find_by_user_id(params[:user_id])
|
||||
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
|
||||
else
|
||||
if team_member.errors[:project_access].any?
|
||||
error!(team_member.errors[:project_access], 422)
|
||||
end
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -177,6 +177,34 @@ describe Gitlab::API do
|
|||
json_response['email'].should == user2.email
|
||||
json_response['access_level'].should == UsersProject::DEVELOPER
|
||||
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
|
||||
|
||||
describe "PUT /projects/:id/members/:user_id" do
|
||||
|
@ -186,6 +214,21 @@ describe Gitlab::API do
|
|||
json_response['email'].should == user3.email
|
||||
json_response['access_level'].should == UsersProject::MASTER
|
||||
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
|
||||
|
||||
describe "DELETE /projects/:id/members/:user_id" do
|
||||
|
|
Loading…
Reference in a new issue