debian-mirror-gitlab/spec/requests/api/badges_spec.rb

397 lines
15 KiB
Ruby
Raw Normal View History

2019-12-26 22:10:19 +05:30
# frozen_string_literal: true
2018-03-27 19:54:05 +05:30
require 'spec_helper'
2023-03-04 22:38:38 +05:30
RSpec.describe API::Badges, feature_category: :projects do
2018-11-18 11:00:15 +05:30
let(:maintainer) { create(:user, username: 'maintainer_user') }
2018-03-27 19:54:05 +05:30
let(:developer) { create(:user) }
let(:access_requester) { create(:user) }
let(:stranger) { create(:user) }
let(:project_group) { create(:group) }
let(:project) { setup_project }
let!(:group) { setup_group }
shared_context 'source helpers' do
def get_source(source_type)
source_type == 'project' ? project : group
end
end
shared_examples 'GET /:sources/:id/badges' do |source_type|
include_context 'source helpers'
let(:source) { get_source(source_type) }
context "with :sources == #{source_type.pluralize}" do
it_behaves_like 'a 404 response when source is private' do
let(:route) { get api("/#{source_type.pluralize}/#{source.id}/badges", stranger) }
end
2018-11-18 11:00:15 +05:30
%i[maintainer developer access_requester stranger].each do |type|
2018-03-27 19:54:05 +05:30
context "when authenticated as a #{type}" do
it 'returns 200' do
user = public_send(type)
badges_count = source_type == 'project' ? 3 : 2
get api("/#{source_type.pluralize}/#{source.id}/badges", user)
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:ok)
2018-03-27 19:54:05 +05:30
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(badges_count)
end
end
end
it 'avoids N+1 queries' do
# Establish baseline
2018-11-18 11:00:15 +05:30
get api("/#{source_type.pluralize}/#{source.id}/badges", maintainer)
2018-03-27 19:54:05 +05:30
control = ActiveRecord::QueryRecorder.new do
2018-11-18 11:00:15 +05:30
get api("/#{source_type.pluralize}/#{source.id}/badges", maintainer)
2018-03-27 19:54:05 +05:30
end
project.add_developer(create(:user))
expect do
2018-11-18 11:00:15 +05:30
get api("/#{source_type.pluralize}/#{source.id}/badges", maintainer)
2018-03-27 19:54:05 +05:30
end.not_to exceed_query_limit(control)
end
end
end
shared_examples 'GET /:sources/:id/badges/:badge_id' do |source_type|
include_context 'source helpers'
let(:source) { get_source(source_type) }
context "with :sources == #{source_type.pluralize}" do
it_behaves_like 'a 404 response when source is private' do
let(:route) { get api("/#{source_type.pluralize}/#{source.id}/badges/#{developer.id}", stranger) }
end
context 'when authenticated as a non-member' do
2018-11-18 11:00:15 +05:30
%i[maintainer developer access_requester stranger].each do |type|
2018-03-27 19:54:05 +05:30
let(:badge) { source.badges.first }
context "as a #{type}" do
2019-07-31 22:56:46 +05:30
it 'returns 200', :quarantine do
2018-03-27 19:54:05 +05:30
user = public_send(type)
get api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", user)
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:ok)
2020-01-01 13:55:28 +05:30
expect(json_response['name']).to eq(badge.name)
2018-03-27 19:54:05 +05:30
expect(json_response['id']).to eq(badge.id)
expect(json_response['link_url']).to eq(badge.link_url)
expect(json_response['rendered_link_url']).to eq(badge.rendered_link_url)
expect(json_response['image_url']).to eq(badge.image_url)
expect(json_response['rendered_image_url']).to eq(badge.rendered_image_url)
expect(json_response['kind']).to eq source_type
end
end
end
end
end
end
shared_examples 'POST /:sources/:id/badges' do |source_type|
include_context 'source helpers'
let(:source) { get_source(source_type) }
2020-01-01 13:55:28 +05:30
let(:example_name) { 'BadgeName' }
2018-03-27 19:54:05 +05:30
let(:example_url) { 'http://www.example.com' }
let(:example_url2) { 'http://www.example1.com' }
context "with :sources == #{source_type.pluralize}" do
it_behaves_like 'a 404 response when source is private' do
let(:route) do
post api("/#{source_type.pluralize}/#{source.id}/badges", stranger),
2020-01-01 13:55:28 +05:30
params: { name: example_name, link_url: example_url, image_url: example_url2 }
2018-03-27 19:54:05 +05:30
end
end
context 'when authenticated as a non-member or member with insufficient rights' do
%i[access_requester stranger developer].each do |type|
context "as a #{type}" do
it 'returns 403' do
user = public_send(type)
post api("/#{source_type.pluralize}/#{source.id}/badges", user),
2019-02-15 15:39:39 +05:30
params: { link_url: example_url, image_url: example_url2 }
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:forbidden)
2018-03-27 19:54:05 +05:30
end
end
end
end
2018-11-18 11:00:15 +05:30
context 'when authenticated as a maintainer/owner' do
2018-03-27 19:54:05 +05:30
it 'creates a new badge' do
expect do
2018-11-18 11:00:15 +05:30
post api("/#{source_type.pluralize}/#{source.id}/badges", maintainer),
2020-01-01 13:55:28 +05:30
params: { name: example_name, link_url: example_url, image_url: example_url2 }
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:created)
2018-03-27 19:54:05 +05:30
end.to change { source.badges.count }.by(1)
2020-01-01 13:55:28 +05:30
expect(json_response['name']).to eq(example_name)
2018-03-27 19:54:05 +05:30
expect(json_response['link_url']).to eq(example_url)
expect(json_response['image_url']).to eq(example_url2)
expect(json_response['kind']).to eq source_type
end
end
it 'returns 400 when link_url is not given' do
2018-11-18 11:00:15 +05:30
post api("/#{source_type.pluralize}/#{source.id}/badges", maintainer),
2019-02-15 15:39:39 +05:30
params: { link_url: example_url }
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:bad_request)
2018-03-27 19:54:05 +05:30
end
it 'returns 400 when image_url is not given' do
2018-11-18 11:00:15 +05:30
post api("/#{source_type.pluralize}/#{source.id}/badges", maintainer),
2019-02-15 15:39:39 +05:30
params: { image_url: example_url2 }
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:bad_request)
2018-03-27 19:54:05 +05:30
end
it 'returns 400 when link_url or image_url is not valid' do
2018-11-18 11:00:15 +05:30
post api("/#{source_type.pluralize}/#{source.id}/badges", maintainer),
2019-02-15 15:39:39 +05:30
params: { link_url: 'whatever', image_url: 'whatever' }
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:bad_request)
2018-03-27 19:54:05 +05:30
end
end
end
shared_examples 'PUT /:sources/:id/badges/:badge_id' do |source_type|
include_context 'source helpers'
let(:source) { get_source(source_type) }
context "with :sources == #{source_type.pluralize}" do
let(:badge) { source.badges.first }
2020-01-01 13:55:28 +05:30
let(:example_name) { 'BadgeName' }
2018-03-27 19:54:05 +05:30
let(:example_url) { 'http://www.example.com' }
let(:example_url2) { 'http://www.example1.com' }
it_behaves_like 'a 404 response when source is private' do
let(:route) do
put api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", stranger),
2019-02-15 15:39:39 +05:30
params: { link_url: example_url }
2018-03-27 19:54:05 +05:30
end
end
context 'when authenticated as a non-member or member with insufficient rights' do
%i[access_requester stranger developer].each do |type|
context "as a #{type}" do
it 'returns 403' do
user = public_send(type)
put api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", user),
2019-02-15 15:39:39 +05:30
params: { link_url: example_url }
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:forbidden)
2018-03-27 19:54:05 +05:30
end
end
end
end
2018-11-18 11:00:15 +05:30
context 'when authenticated as a maintainer/owner' do
2019-07-31 22:56:46 +05:30
it 'updates the member', :quarantine do
2018-11-18 11:00:15 +05:30
put api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", maintainer),
2020-01-01 13:55:28 +05:30
params: { name: example_name, link_url: example_url, image_url: example_url2 }
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:ok)
2020-01-01 13:55:28 +05:30
expect(json_response['name']).to eq(example_name)
2018-03-27 19:54:05 +05:30
expect(json_response['link_url']).to eq(example_url)
expect(json_response['image_url']).to eq(example_url2)
expect(json_response['kind']).to eq source_type
end
end
it 'returns 400 when link_url or image_url is not valid' do
2018-11-18 11:00:15 +05:30
put api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", maintainer),
2019-02-15 15:39:39 +05:30
params: { link_url: 'whatever', image_url: 'whatever' }
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:bad_request)
2018-03-27 19:54:05 +05:30
end
end
end
shared_examples 'DELETE /:sources/:id/badges/:badge_id' do |source_type|
include_context 'source helpers'
let(:source) { get_source(source_type) }
context "with :sources == #{source_type.pluralize}" do
let(:badge) { source.badges.first }
it_behaves_like 'a 404 response when source is private' do
let(:route) { delete api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", stranger) }
end
context 'when authenticated as a non-member or member with insufficient rights' do
%i[access_requester developer stranger].each do |type|
context "as a #{type}" do
it 'returns 403' do
user = public_send(type)
delete api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", user)
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:forbidden)
2018-03-27 19:54:05 +05:30
end
end
end
end
2019-07-31 22:56:46 +05:30
context 'when authenticated as a maintainer/owner', :quarantine do
2018-03-27 19:54:05 +05:30
it 'deletes the badge' do
expect do
2018-11-18 11:00:15 +05:30
delete api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", maintainer)
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:no_content)
2018-03-27 19:54:05 +05:30
end.to change { source.badges.count }.by(-1)
end
it_behaves_like '412 response' do
2018-11-18 11:00:15 +05:30
let(:request) { api("/#{source_type.pluralize}/#{source.id}/badges/#{badge.id}", maintainer) }
2018-03-27 19:54:05 +05:30
end
end
it 'returns 404 if badge does not exist' do
2018-11-18 11:00:15 +05:30
delete api("/#{source_type.pluralize}/#{source.id}/badges/123", maintainer)
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:not_found)
2018-03-27 19:54:05 +05:30
end
end
end
shared_examples 'GET /:sources/:id/badges/render' do |source_type|
include_context 'source helpers'
let(:source) { get_source(source_type) }
let(:example_url) { 'http://www.example.com' }
let(:example_url2) { 'http://www.example1.com' }
context "with :sources == #{source_type.pluralize}" do
it_behaves_like 'a 404 response when source is private' do
let(:route) do
get api("/#{source_type.pluralize}/#{source.id}/badges/render?link_url=#{example_url}&image_url=#{example_url2}", stranger)
end
end
context 'when authenticated as a non-member or member with insufficient rights' do
%i[access_requester stranger developer].each do |type|
context "as a #{type}" do
it 'returns 403' do
user = public_send(type)
get api("/#{source_type.pluralize}/#{source.id}/badges/render?link_url=#{example_url}&image_url=#{example_url2}", user)
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:forbidden)
2018-03-27 19:54:05 +05:30
end
end
end
end
2018-11-18 11:00:15 +05:30
context 'when authenticated as a maintainer/owner' do
2018-03-27 19:54:05 +05:30
it 'gets the rendered badge values' do
2018-11-18 11:00:15 +05:30
get api("/#{source_type.pluralize}/#{source.id}/badges/render?link_url=#{example_url}&image_url=#{example_url2}", maintainer)
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:ok)
2018-03-27 19:54:05 +05:30
2020-01-01 13:55:28 +05:30
expect(json_response.keys).to contain_exactly('name', 'link_url', 'rendered_link_url', 'image_url', 'rendered_image_url')
2018-03-27 19:54:05 +05:30
expect(json_response['link_url']).to eq(example_url)
expect(json_response['image_url']).to eq(example_url2)
expect(json_response['rendered_link_url']).to eq(example_url)
expect(json_response['rendered_image_url']).to eq(example_url2)
end
end
it 'returns 400 when link_url is not given' do
2018-11-18 11:00:15 +05:30
get api("/#{source_type.pluralize}/#{source.id}/badges/render?link_url=#{example_url}", maintainer)
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:bad_request)
2018-03-27 19:54:05 +05:30
end
it 'returns 400 when image_url is not given' do
2018-11-18 11:00:15 +05:30
get api("/#{source_type.pluralize}/#{source.id}/badges/render?image_url=#{example_url}", maintainer)
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:bad_request)
2018-03-27 19:54:05 +05:30
end
it 'returns 400 when link_url or image_url is not valid' do
2018-11-18 11:00:15 +05:30
get api("/#{source_type.pluralize}/#{source.id}/badges/render?link_url=whatever&image_url=whatever", maintainer)
2018-03-27 19:54:05 +05:30
2020-04-08 14:13:33 +05:30
expect(response).to have_gitlab_http_status(:bad_request)
2018-03-27 19:54:05 +05:30
end
end
end
context 'when deleting a badge' do
context 'and the source is a project' do
2020-09-03 11:15:55 +05:30
let(:badge) { project.group.badges.first }
2018-03-27 19:54:05 +05:30
it 'cannot delete badges owned by the project group' do
2020-09-03 11:15:55 +05:30
expect do
delete api("/projects/#{project.id}/badges/#{badge.id}", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
end.not_to change { badge.reload.persisted? }
end
end
end
context 'when updating a badge' do
context 'and the source is a project' do
let(:badge) { project.group.badges.first }
let(:example_name) { 'BadgeName' }
let(:example_url) { 'http://www.example.com' }
let(:example_url2) { 'http://www.example1.com' }
it 'cannot update badges owned by the project group' do
expect do
put api("/projects/#{project.id}/badges/#{badge.id}", maintainer),
params: { name: example_name, link_url: example_url, image_url: example_url2 }
2018-03-27 19:54:05 +05:30
2020-09-03 11:15:55 +05:30
expect(response).to have_gitlab_http_status(:not_found)
end.not_to change { badge.reload.updated_at }
2018-03-27 19:54:05 +05:30
end
end
end
describe 'Endpoints' do
%w(project group).each do |source_type|
it_behaves_like 'GET /:sources/:id/badges', source_type
it_behaves_like 'GET /:sources/:id/badges/:badge_id', source_type
it_behaves_like 'GET /:sources/:id/badges/render', source_type
it_behaves_like 'POST /:sources/:id/badges', source_type
it_behaves_like 'PUT /:sources/:id/badges/:badge_id', source_type
it_behaves_like 'DELETE /:sources/:id/badges/:badge_id', source_type
end
end
def setup_project
2019-12-21 20:55:43 +05:30
create(:project, :public, creator_id: maintainer.id, namespace: project_group) do |project|
2018-03-27 19:54:05 +05:30
project.add_developer(developer)
2018-11-18 11:00:15 +05:30
project.add_maintainer(maintainer)
2018-03-27 19:54:05 +05:30
project.request_access(access_requester)
2020-01-01 13:55:28 +05:30
project.project_badges << build(:project_badge, project: project, name: 'ExampleBadge1')
project.project_badges << build(:project_badge, project: project, name: 'ExampleBadge2')
project_group.badges << build(:group_badge, group: group, name: 'ExampleBadge3')
2018-03-27 19:54:05 +05:30
end
end
def setup_group
2019-12-21 20:55:43 +05:30
create(:group, :public) do |group|
2018-03-27 19:54:05 +05:30
group.add_developer(developer)
2018-11-18 11:00:15 +05:30
group.add_owner(maintainer)
2018-03-27 19:54:05 +05:30
group.request_access(access_requester)
2020-01-01 13:55:28 +05:30
group.badges << build(:group_badge, group: group, name: 'ExampleBadge4')
group.badges << build(:group_badge, group: group, name: 'ExampleBadge5')
2018-03-27 19:54:05 +05:30
end
end
end