diff options
-rw-r--r-- | lib/api/helpers.rb | 1 | ||||
-rw-r--r-- | lib/api/members.rb | 45 | ||||
-rw-r--r-- | spec/requests/api/group_members_spec.rb | 10 | ||||
-rw-r--r-- | spec/requests/api/members_spec.rb | 22 | ||||
-rw-r--r-- | spec/requests/api/project_members_spec.rb | 31 |
5 files changed, 72 insertions, 37 deletions
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index f06c262fd4c..d0469d6602d 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -47,7 +47,6 @@ module API end end - # Deprecated def user_project @project ||= find_project(params[:id]) end diff --git a/lib/api/members.rb b/lib/api/members.rb index 56f8b1ca391..ccb7618360d 100644 --- a/lib/api/members.rb +++ b/lib/api/members.rb @@ -65,14 +65,29 @@ module API ::Members::DestroyService.new(access_requester, access_requester.user).execute end - conflict!('Member already exists') if source.members.exists?(user_id: params[:user_id]) - - source.add_user(params[:user_id], params[:access_level], current_user) member = source.members.find_by(user_id: params[:user_id]) + + # This is to ensure back-compatibility but 409 behavior should be used + # for both project and group members in 9.0! + conflict!('Member already exists') if source_type == 'group' && member + + unless member + source.add_user(params[:user_id], params[:access_level], current_user) + member = source.members.find_by(user_id: params[:user_id]) + end + if member present member.user, with: Entities::Member, member: member else - render_api_error!('400 Bad Request', 400) + # Since `source.add_user` doesn't return a member object, we have to + # build a new one and populate its errors in order to render them. + member = source.members.build(attributes_for_keys([:user_id, :access_level])) + member.valid? # populate the errors + + # This is to ensure back-compatibility but 400 behavior should be used + # for all validation errors in 9.0! + render_api_error!('Access level is not known', 422) if member.errors.key?(:access_level) + render_validation_error!(member) end end @@ -96,6 +111,9 @@ module API if member.update_attributes(access_level: params[:access_level]) present member.user, with: Entities::Member, member: member else + # This is to ensure back-compatibility but 400 behavior should be used + # for all validation errors in 9.0! + render_api_error!('Access level is not known', 422) if member.errors.key?(:access_level) render_validation_error!(member) end end @@ -113,10 +131,23 @@ module API source = find_source(source_type, params[:id]) required_attributes! [:user_id] - member = source.members.find_by!(user_id: params[:user_id]) + # This is to ensure back-compatibility but find_by! should be used + # in that casse in 9.0! + member = source.members.find_by(user_id: params[:user_id]) + + # This is to ensure back-compatibility but this should be removed in + # favor of find_by! in 9.0! + not_found!("Member: user_id:#{params[:user_id]}") if source_type == 'group' && member.nil? + + # This is to ensure back-compatibility but 204 behavior should be used + # for all DELETE endpoints in 9.0! + if member.nil? + { message: "Access revoked", id: params[:user_id].to_i } + else + ::Members::DestroyService.new(member, current_user).execute - ::Members::DestroyService.new(member, current_user).execute - status :no_content + present member.user, with: Entities::Member, member: member + end end end end diff --git a/spec/requests/api/group_members_spec.rb b/spec/requests/api/group_members_spec.rb index cdb3d7ddf4a..8bd6a8062ae 100644 --- a/spec/requests/api/group_members_spec.rb +++ b/spec/requests/api/group_members_spec.rb @@ -96,9 +96,9 @@ describe API::API, api: true do expect(response).to have_http_status(400) end - it "returns a 400 error when access level is not known" do + it "returns a 422 error when access level is not known" do post api("/groups/#{group_no_members.id}/members", owner), user_id: master.id, access_level: 1234 - expect(response).to have_http_status(400) + expect(response).to have_http_status(422) end end end @@ -156,12 +156,12 @@ describe API::API, api: true do expect(response).to have_http_status(400) end - it 'returns a 400 error when access level is not known' do + it 'returns a 422 error when access level is not known' do put( api("/groups/#{group_with_members.id}/members/#{master.id}", owner), access_level: 1234 ) - expect(response).to have_http_status(400) + expect(response).to have_http_status(422) end end end @@ -182,7 +182,7 @@ describe API::API, api: true do delete api("/groups/#{group_with_members.id}/members/#{guest.id}", owner) end.to change { group_with_members.members.count }.by(-1) - expect(response).to have_http_status(204) + expect(response).to have_http_status(200) end it "returns a 404 error when user id is not known" do diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb index b11a16487ac..a56ee30f7b1 100644 --- a/spec/requests/api/members_spec.rb +++ b/spec/requests/api/members_spec.rb @@ -135,7 +135,7 @@ describe API::Members, api: true do post api("/#{source_type.pluralize}/#{source.id}/members", master), user_id: master.id, access_level: Member::MASTER - expect(response).to have_http_status(409) + expect(response).to have_http_status(source_type == 'project' ? 201 : 409) end it 'returns 400 when user_id is not given' do @@ -152,11 +152,11 @@ describe API::Members, api: true do expect(response).to have_http_status(400) end - it 'returns 400 when access_level is not valid' do + it 'returns 422 when access_level is not valid' do post api("/#{source_type.pluralize}/#{source.id}/members", master), user_id: stranger.id, access_level: 1234 - expect(response).to have_http_status(400) + expect(response).to have_http_status(422) end end end @@ -204,11 +204,11 @@ describe API::Members, api: true do expect(response).to have_http_status(400) end - it 'returns 400 when access level is not valid' do + it 'returns 422 when access level is not valid' do put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master), access_level: 1234 - expect(response).to have_http_status(400) + expect(response).to have_http_status(422) end end end @@ -237,18 +237,18 @@ describe API::Members, api: true do expect do delete api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", developer) - expect(response).to have_http_status(204) + expect(response).to have_http_status(200) end.to change { source.members.count }.by(-1) end end context 'when authenticated as a master/owner' do context 'and member is a requester' do - it 'returns 404' do + it "returns #{source_type == 'project' ? 200 : 404}" do expect do delete api("/#{source_type.pluralize}/#{source.id}/members/#{access_requester.id}", master) - expect(response).to have_http_status(404) + expect(response).to have_http_status(source_type == 'project' ? 200 : 404) end.not_to change { source.requesters.count } end end @@ -257,15 +257,15 @@ describe API::Members, api: true do expect do delete api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master) - expect(response).to have_http_status(204) + expect(response).to have_http_status(200) end.to change { source.members.count }.by(-1) end end - it 'returns 409 if member does not exist' do + it "returns #{source_type == 'project' ? 200 : 404} if member does not exist" do delete api("/#{source_type.pluralize}/#{source.id}/members/123", master) - expect(response).to have_http_status(404) + expect(response).to have_http_status(source_type == 'project' ? 200 : 404) end end end diff --git a/spec/requests/api/project_members_spec.rb b/spec/requests/api/project_members_spec.rb index 195d5bb3f8f..061c7b78edb 100644 --- a/spec/requests/api/project_members_spec.rb +++ b/spec/requests/api/project_members_spec.rb @@ -62,7 +62,7 @@ describe API::API, api: true do expect(json_response['access_level']).to eq(ProjectMember::DEVELOPER) end - it "returns a 409 status if user is already project member" do + it "returns a 201 status if user is already project member" do post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: ProjectMember::DEVELOPER @@ -70,7 +70,9 @@ describe API::API, api: true do post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: ProjectMember::DEVELOPER end.not_to change { ProjectMember.count } - expect(response).to have_http_status(409) + expect(response).to have_http_status(201) + expect(json_response['username']).to eq(user2.username) + expect(json_response['access_level']).to eq(ProjectMember::DEVELOPER) end it "returns a 400 error when user id is not given" do @@ -83,9 +85,9 @@ describe API::API, api: true do expect(response).to have_http_status(400) end - it "returns a 400 error when access level is not known" do + it "returns a 422 error when access level is not known" do post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: 1234 - expect(response).to have_http_status(400) + expect(response).to have_http_status(422) end end @@ -109,9 +111,9 @@ describe API::API, api: true do expect(response).to have_http_status(400) end - it "returns a 400 error when access level is not known" do + it "returns a 422 error when access level is not known" do put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: 123 - expect(response).to have_http_status(400) + expect(response).to have_http_status(422) end end @@ -127,25 +129,27 @@ describe API::API, api: true do end.to change { ProjectMember.count }.by(-1) end - it "returns 404 if team member is not part of a project" do + it "returns 200 if team member is not part of a project" do delete api("/projects/#{project.id}/members/#{user3.id}", user) expect do delete api("/projects/#{project.id}/members/#{user3.id}", user) end.not_to change { ProjectMember.count } - expect(response).to have_http_status(404) + expect(response).to have_http_status(200) end - it "returns 404 if team member already removed" do + it "returns 200 if team member already removed" do delete api("/projects/#{project.id}/members/#{user3.id}", user) delete api("/projects/#{project.id}/members/#{user3.id}", user) - expect(response).to have_http_status(404) + expect(response).to have_http_status(200) end - it "returns 404 when the user was not member" do + it "returns 200 OK when the user was not member" do expect do delete api("/projects/#{project.id}/members/1000000", user) end.to change { ProjectMember.count }.by(0) - expect(response).to have_http_status(404) + expect(response).to have_http_status(200) + expect(json_response['id']).to eq(1000000) + expect(json_response['message']).to eq('Access revoked') end context 'when the user is not an admin or owner' do @@ -154,7 +158,8 @@ describe API::API, api: true do delete api("/projects/#{project.id}/members/#{user3.id}", user3) end.to change { ProjectMember.count }.by(-1) - expect(response).to have_http_status(204) + expect(response).to have_http_status(200) + expect(json_response['id']).to eq(user3.id) end end end |