gitlab-org--gitlab-foss/spec/requests/api/releases_spec.rb

533 lines
16 KiB
Ruby
Raw Normal View History

require 'spec_helper'
describe API::Releases do
let(:project) { create(:project, :repository, :private) }
let(:maintainer) { create(:user) }
let(:reporter) { create(:user) }
let(:non_project_member) { create(:user) }
let(:commit) { create(:commit, project: project) }
before do
project.add_maintainer(maintainer)
project.add_reporter(reporter)
project.repository.add_tag(maintainer, 'v0.1', commit.id)
project.repository.add_tag(maintainer, 'v0.2', commit.id)
end
describe 'GET /projects/:id/releases' do
context 'when there are two releases' do
let!(:release_1) do
create(:release,
project: project,
tag: 'v0.1',
author: maintainer,
created_at: 2.days.ago)
end
let!(:release_2) do
create(:release,
project: project,
tag: 'v0.2',
author: maintainer,
created_at: 1.day.ago)
end
it 'returns 200 HTTP status' do
get api("/projects/#{project.id}/releases", maintainer)
expect(response).to have_gitlab_http_status(:ok)
end
it 'returns releases ordered by created_at' do
get api("/projects/#{project.id}/releases", maintainer)
expect(json_response.count).to eq(2)
expect(json_response.first['tag_name']).to eq(release_2.tag)
expect(json_response.second['tag_name']).to eq(release_1.tag)
end
it 'matches response schema' do
get api("/projects/#{project.id}/releases", maintainer)
expect(response).to match_response_schema('releases')
end
end
context 'when tag does not exist in git repository' do
let!(:release) { create(:release, project: project, tag: 'v1.1.5') }
it 'returns the tag' do
get api("/projects/#{project.id}/releases", maintainer)
expect(json_response.count).to eq(1)
expect(json_response.first['tag_name']).to eq('v1.1.5')
expect(release).to be_tag_missing
end
end
context 'when user is not a project member' do
it 'cannot find the project' do
get api("/projects/#{project.id}/releases", non_project_member)
expect(response).to have_gitlab_http_status(:not_found)
end
context 'when project is public' do
let(:project) { create(:project, :repository, :public) }
it 'allows the request' do
get api("/projects/#{project.id}/releases", non_project_member)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(releases_page: false)
end
it 'cannot find the API' do
get api("/projects/#{project.id}/releases", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
describe 'GET /projects/:id/releases/:tag_name' do
context 'when there is a release' do
let!(:release) do
create(:release,
project: project,
tag: 'v0.1',
sha: commit.id,
author: maintainer,
description: 'This is v0.1')
end
it 'returns 200 HTTP status' do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(response).to have_gitlab_http_status(:ok)
end
it 'returns a release entry' do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(json_response['tag_name']).to eq(release.tag)
expect(json_response['description']).to eq('This is v0.1')
expect(json_response['author']['name']).to eq(maintainer.name)
expect(json_response['commit']['id']).to eq(commit.id)
end
it 'matches response schema' do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(response).to match_response_schema('release')
end
end
context 'when specified tag is not found in the project' do
it 'cannot find the release entry' do
get api("/projects/#{project.id}/releases/non_exist_tag", maintainer)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when user is not a project member' do
let!(:release) { create(:release, tag: 'v0.1', project: project) }
it 'cannot find the project' do
get api("/projects/#{project.id}/releases/v0.1", non_project_member)
expect(response).to have_gitlab_http_status(:not_found)
end
context 'when project is public' do
let(:project) { create(:project, :repository, :public) }
it 'allows the request' do
get api("/projects/#{project.id}/releases/v0.1", non_project_member)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(releases_page: false)
end
it 'cannot find the API' do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
describe 'POST /projects/:id/releases' do
let(:params) do
{
name: 'New release',
tag_name: 'v0.1',
description: 'Super nice release'
}
end
it 'accepts the request' do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to have_gitlab_http_status(:created)
end
it 'creates a new release' do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.to change { Release.count }.by(1)
expect(project.releases.last.name).to eq('New release')
expect(project.releases.last.tag).to eq('v0.1')
expect(project.releases.last.description).to eq('Super nice release')
end
context 'when description is empty' do
let(:params) do
{
name: 'New release',
tag_name: 'v0.1',
description: ''
}
end
it 'returns an error as validation failure' do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.not_to change { Release.count }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message'])
.to eq("Validation failed: Description can't be blank")
end
end
it 'matches response schema' do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to match_response_schema('release')
end
it 'does not create a new tag' do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.not_to change { Project.find_by_id(project.id).repository.tag_count }
end
context 'when user is a reporter' do
it 'forbids the request' do
post api("/projects/#{project.id}/releases", reporter), params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when user is not a project member' do
it 'forbids the request' do
post api("/projects/#{project.id}/releases", non_project_member),
params: params
expect(response).to have_gitlab_http_status(:not_found)
end
context 'when project is public' do
let(:project) { create(:project, :repository, :public) }
it 'forbids the request' do
post api("/projects/#{project.id}/releases", non_project_member),
params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when tag does not exist in git repository' do
let(:params) do
{
name: 'Android ~ Ice Cream Sandwich ~',
tag_name: tag_name,
description: 'Android 4.04.0.4 "Ice Cream Sandwich" is the ninth' \
'version of the Android mobile operating system developed' \
'by Google.',
ref: 'master'
}
end
let(:tag_name) { 'v4.0' }
it 'creates a new tag' do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.to change { Project.find_by_id(project.id).repository.tag_count }.by(1)
expect(project.repository.find_tag('v4.0').dereferenced_target.id)
.to eq(project.repository.commit('master').id)
end
it 'creates a new release' do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.to change { Release.count }.by(1)
expect(project.releases.last.name).to eq('Android ~ Ice Cream Sandwich ~')
expect(project.releases.last.tag).to eq('v4.0')
expect(project.releases.last.description).to eq(
'Android 4.04.0.4 "Ice Cream Sandwich" is the ninth' \
'version of the Android mobile operating system developed' \
'by Google.')
end
context 'when tag name is HEAD' do
let(:tag_name) { 'HEAD' }
it 'returns an error as failure on tag creation' do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(json_response['message']).to eq('Tag name invalid')
end
end
context 'when tag name is empty' do
let(:tag_name) { '' }
it 'returns an error as failure on tag creation' do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(json_response['message']).to eq('Tag name invalid')
end
end
end
context 'when release already exists' do
before do
create(:release, project: project, tag: 'v0.1', name: 'New release')
end
it 'returns an error as conflicted request' do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to have_gitlab_http_status(:conflict)
end
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(releases_page: false)
end
it 'cannot find the API' do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
describe 'PUT /projects/:id/releases/:tag_name' do
let(:params) { { description: 'Best release ever!' } }
let!(:release) do
create(:release,
project: project,
tag: 'v0.1',
name: 'New release',
description: 'Super nice release')
end
it 'accepts the request' do
put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
expect(response).to have_gitlab_http_status(:ok)
end
it 'updates the description' do
put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
expect(project.releases.last.description).to eq('Best release ever!')
end
it 'does not change other attributes' do
put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
expect(project.releases.last.tag).to eq('v0.1')
expect(project.releases.last.name).to eq('New release')
end
it 'matches response schema' do
put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
expect(response).to match_response_schema('release')
end
context 'when user tries to update sha' do
let(:params) { { sha: 'xxx' } }
it 'does not allow the request' do
put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
expect(response).to have_gitlab_http_status(:bad_request)
end
end
context 'when params is empty' do
let(:params) { {} }
it 'does not allow the request' do
put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
expect(response).to have_gitlab_http_status(:bad_request)
end
end
context 'when there are no corresponding releases' do
let!(:release) { }
it 'forbids the request' do
put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when user is a reporter' do
it 'forbids the request' do
put api("/projects/#{project.id}/releases/v0.1", reporter), params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when user is not a project member' do
it 'forbids the request' do
put api("/projects/#{project.id}/releases/v0.1", non_project_member),
params: params
expect(response).to have_gitlab_http_status(:not_found)
end
context 'when project is public' do
let(:project) { create(:project, :repository, :public) }
it 'forbids the request' do
put api("/projects/#{project.id}/releases/v0.1", non_project_member),
params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(releases_page: false)
end
it 'cannot find the API' do
put api("/projects/#{project.id}/releases/v0.1", non_project_member),
params: params
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
describe 'DELETE /projects/:id/releases/:tag_name' do
let!(:release) do
create(:release,
project: project,
tag: 'v0.1',
name: 'New release',
description: 'Super nice release')
end
it 'accepts the request' do
delete api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(response).to have_gitlab_http_status(:ok)
end
it 'destroys the release' do
expect do
delete api("/projects/#{project.id}/releases/v0.1", maintainer)
end.to change { Release.count }.by(-1)
end
it 'does not remove a tag in repository' do
expect do
delete api("/projects/#{project.id}/releases/v0.1", maintainer)
end.not_to change { Project.find_by_id(project.id).repository.tag_count }
end
it 'matches response schema' do
delete api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(response).to match_response_schema('release')
end
context 'when there are no corresponding releases' do
let!(:release) { }
it 'forbids the request' do
delete api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when user is a reporter' do
it 'forbids the request' do
delete api("/projects/#{project.id}/releases/v0.1", reporter)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when user is not a project member' do
it 'forbids the request' do
delete api("/projects/#{project.id}/releases/v0.1", non_project_member)
expect(response).to have_gitlab_http_status(:not_found)
end
context 'when project is public' do
let(:project) { create(:project, :repository, :public) }
it 'forbids the request' do
delete api("/projects/#{project.id}/releases/v0.1", non_project_member)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(releases_page: false)
end
it 'cannot find the API' do
delete api("/projects/#{project.id}/releases/v0.1", non_project_member)
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end