Commit 158ea1a6 authored by Toon Claes's avatar Toon Claes

Ensure v3 environments endpoints remain unchanged

Because environments also expose the project, ensure the projects are
exposed as they were before in API v3.
parent 45cc856c
......@@ -188,6 +188,10 @@ module API
expose :projects, using: Entities::Project
expose :shared_projects, using: Entities::Project
end
class Environment < ::API::Entities::EnvironmentBasic
expose :project, using: Entities::Project
end
end
end
end
module API
module V3
class Environments < Grape::API
include ::API::Helpers::CustomValidators
include PaginationParams
before { authenticate! }
......@@ -9,9 +10,66 @@ module API
requires :id, type: String, desc: 'The project ID'
end
resource :projects do
desc 'Get all environments of the project' do
detail 'This feature was introduced in GitLab 8.11.'
success Entities::Environment
end
params do
use :pagination
end
get ':id/environments' do
authorize! :read_environment, user_project
present paginate(user_project.environments), with: Entities::Environment
end
desc 'Creates a new environment' do
detail 'This feature was introduced in GitLab 8.11.'
success Entities::Environment
end
params do
requires :name, type: String, desc: 'The name of the environment to be created'
optional :external_url, type: String, desc: 'URL on which this deployment is viewable'
optional :slug, absence: { message: "is automatically generated and cannot be changed" }
end
post ':id/environments' do
authorize! :create_environment, user_project
environment = user_project.environments.create(declared_params)
if environment.persisted?
present environment, with: Entities::Environment
else
render_validation_error!(environment)
end
end
desc 'Updates an existing environment' do
detail 'This feature was introduced in GitLab 8.11.'
success Entities::Environment
end
params do
requires :environment_id, type: Integer, desc: 'The environment ID'
optional :name, type: String, desc: 'The new environment name'
optional :external_url, type: String, desc: 'The new URL on which this deployment is viewable'
optional :slug, absence: { message: "is automatically generated and cannot be changed" }
end
put ':id/environments/:environment_id' do
authorize! :update_environment, user_project
environment = user_project.environments.find(params[:environment_id])
update_params = declared_params(include_missing: false).extract!(:name, :external_url)
if environment.update(update_params)
present environment, with: Entities::Environment
else
render_validation_error!(environment)
end
end
desc 'Deletes an existing environment' do
detail 'This feature was introduced in GitLab 8.11.'
success ::API::Entities::Environment
success Entities::Environment
end
params do
requires :environment_id, type: Integer, desc: 'The environment ID'
......@@ -21,7 +79,7 @@ module API
environment = user_project.environments.find(params[:environment_id])
present environment.destroy, with: ::API::Entities::Environment
present environment.destroy, with: Entities::Environment
end
end
end
......
......@@ -24,6 +24,7 @@ describe API::Environments, api: true do
expect(json_response.first['name']).to eq(environment.name)
expect(json_response.first['external_url']).to eq(environment.external_url)
expect(json_response.first['project']['id']).to eq(project.id)
expect(json_response.first['project']['visibility']).to be_present
end
end
......
......@@ -12,6 +12,132 @@ describe API::V3::Environments, api: true do
project.team << [user, :master]
end
shared_examples 'a paginated resources' do
before do
# Fires the request
request
end
it 'has pagination headers' do
expect(response.headers).to include('X-Total')
expect(response.headers).to include('X-Total-Pages')
expect(response.headers).to include('X-Per-Page')
expect(response.headers).to include('X-Page')
expect(response.headers).to include('X-Next-Page')
expect(response.headers).to include('X-Prev-Page')
expect(response.headers).to include('Link')
end
end
describe 'GET /projects/:id/environments' do
context 'as member of the project' do
it_behaves_like 'a paginated resources' do
let(:request) { get v3_api("/projects/#{project.id}/environments", user) }
end
it 'returns project environments' do
get v3_api("/projects/#{project.id}/environments", user)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
expect(json_response.first['name']).to eq(environment.name)
expect(json_response.first['external_url']).to eq(environment.external_url)
expect(json_response.first['project']['id']).to eq(project.id)
expect(json_response.first['project']['visibility_level']).to be_present
end
end
context 'as non member' do
it 'returns a 404 status code' do
get v3_api("/projects/#{project.id}/environments", non_member)
expect(response).to have_http_status(404)
end
end
end
describe 'POST /projects/:id/environments' do
context 'as a member' do
it 'creates a environment with valid params' do
post v3_api("/projects/#{project.id}/environments", user), name: "mepmep"
expect(response).to have_http_status(201)
expect(json_response['name']).to eq('mepmep')
expect(json_response['slug']).to eq('mepmep')
expect(json_response['external']).to be nil
end
it 'requires name to be passed' do
post v3_api("/projects/#{project.id}/environments", user), external_url: 'test.gitlab.com'
expect(response).to have_http_status(400)
end
it 'returns a 400 if environment already exists' do
post v3_api("/projects/#{project.id}/environments", user), name: environment.name
expect(response).to have_http_status(400)
end
it 'returns a 400 if slug is specified' do
post v3_api("/projects/#{project.id}/environments", user), name: "foo", slug: "foo"
expect(response).to have_http_status(400)
expect(json_response["error"]).to eq("slug is automatically generated and cannot be changed")
end
end
context 'a non member' do
it 'rejects the request' do
post v3_api("/projects/#{project.id}/environments", non_member), name: 'gitlab.com'
expect(response).to have_http_status(404)
end
it 'returns a 400 when the required params are missing' do
post v3_api("/projects/12345/environments", non_member), external_url: 'http://env.git.com'
end
end
end
describe 'PUT /projects/:id/environments/:environment_id' do
it 'returns a 200 if name and external_url are changed' do
url = 'https://mepmep.whatever.ninja'
put v3_api("/projects/#{project.id}/environments/#{environment.id}", user),
name: 'Mepmep', external_url: url
expect(response).to have_http_status(200)
expect(json_response['name']).to eq('Mepmep')
expect(json_response['external_url']).to eq(url)
end
it "won't allow slug to be changed" do
slug = environment.slug
api_url = v3_api("/projects/#{project.id}/environments/#{environment.id}", user)
put api_url, slug: slug + "-foo"
expect(response).to have_http_status(400)
expect(json_response["error"]).to eq("slug is automatically generated and cannot be changed")
end
it "won't update the external_url if only the name is passed" do
url = environment.external_url
put v3_api("/projects/#{project.id}/environments/#{environment.id}", user),
name: 'Mepmep'
expect(response).to have_http_status(200)
expect(json_response['name']).to eq('Mepmep')
expect(json_response['external_url']).to eq(url)
end
it 'returns a 404 if the environment does not exist' do
put v3_api("/projects/#{project.id}/environments/12345", user)
expect(response).to have_http_status(404)
end
end
describe 'DELETE /projects/:id/environments/:environment_id' do
context 'as a master' do
it 'returns a 200 for an existing environment' 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