Commit eab4efd0 authored by Michael Kozono's avatar Michael Kozono

Merge branch 'feature-flag-update-scope-api' into 'master'

Support Create and Update operations for Feature Flag Scope API

See merge request gitlab-org/gitlab!19677
parents f63667a1 d2c628e5
...@@ -21,7 +21,7 @@ module FeatureFlags ...@@ -21,7 +21,7 @@ module FeatureFlags
success(feature_flag: feature_flag) success(feature_flag: feature_flag)
else else
error(feature_flag.errors.full_messages) error(feature_flag.errors.full_messages, :bad_request)
end end
end end
end end
......
...@@ -45,6 +45,29 @@ module API ...@@ -45,6 +45,29 @@ module API
present paginate(feature_flag.scopes), with: EE::API::Entities::FeatureFlag::Scope present paginate(feature_flag.scopes), with: EE::API::Entities::FeatureFlag::Scope
end end
desc 'Create a scope of a feature flag' do
detail 'This feature is going to be introduced in GitLab 12.5 if `feature_flag_api` feature flag is removed'
success EE::API::Entities::FeatureFlag::Scope
end
params do
requires :environment_scope, type: String, desc: 'The environment scope of the scope'
requires :active, type: Boolean, desc: 'Active/inactive of the scope'
requires :strategies, type: JSON, desc: 'The strategies of the scope'
end
post do
authorize_update_feature_flag!
result = ::FeatureFlags::UpdateService
.new(user_project, current_user, scopes_attributes: [declared_params])
.execute(feature_flag)
if result[:status] == :success
present scope, with: EE::API::Entities::FeatureFlag::Scope
else
render_api_error!(result[:message], result[:http_status])
end
end
params do params do
requires :environment_scope, type: String, desc: 'URL-encoded environment scope' requires :environment_scope, type: String, desc: 'URL-encoded environment scope'
end end
...@@ -57,6 +80,33 @@ module API ...@@ -57,6 +80,33 @@ module API
present scope, with: EE::API::Entities::FeatureFlag::Scope present scope, with: EE::API::Entities::FeatureFlag::Scope
end end
desc 'Update a scope of a feature flag' do
detail 'This feature is going to be introduced in GitLab 12.5 if `feature_flag_api` feature flag is removed'
success EE::API::Entities::FeatureFlag::Scope
end
params do
optional :active, type: Boolean, desc: 'Active/inactive of the scope'
optional :strategies, type: JSON, desc: 'The strategies of the scope'
end
put do
authorize_update_feature_flag!
scope_attributes = declared_params.merge(id: scope.id)
result = ::FeatureFlags::UpdateService
.new(user_project, current_user, scopes_attributes: [scope_attributes])
.execute(feature_flag)
if result[:status] == :success
updated_scope = result[:feature_flag].scopes
.find { |scope| scope.environment_scope == params[:environment_scope] }
present updated_scope, with: EE::API::Entities::FeatureFlag::Scope
else
render_api_error!(result[:message], result[:http_status])
end
end
desc 'Delete a scope from a feature flag' do desc 'Delete a scope from a feature flag' do
detail 'This feature is going to be introduced in GitLab 12.5 if `feature_flag_api` feature flag is removed' detail 'This feature is going to be introduced in GitLab 12.5 if `feature_flag_api` feature flag is removed'
success EE::API::Entities::FeatureFlag::Scope success EE::API::Entities::FeatureFlag::Scope
......
...@@ -144,6 +144,56 @@ describe API::FeatureFlagScopes do ...@@ -144,6 +144,56 @@ describe API::FeatureFlagScopes do
end end
end end
describe 'POST /projects/:id/feature_flags/:name/scopes' do
subject do
post api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes", user),
params: params
end
let(:params) do
{
environment_scope: 'staging',
active: true,
strategies: [{ name: 'userWithId', parameters: { 'userIds': 'a,b,c' } }].to_json
}
end
context 'when there is a corresponding feature flag' do
let!(:feature_flag) { create(:operations_feature_flag, project: project) }
it_behaves_like 'check user permission'
it 'creates a new scope' do
subject
expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('public_api/v4/feature_flag_scope', dir: 'ee')
expect(json_response['environment_scope']).to eq(params[:environment_scope])
expect(json_response['active']).to eq(params[:active])
expect(json_response['strategies']).to eq(JSON.parse(params[:strategies]))
end
context 'when the scope already exists' do
before do
create_scope(feature_flag, params[:environment_scope])
end
it 'returns error' do
subject
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to include('Scopes environment scope (staging) has already been taken')
end
end
end
context 'when feature flag is not found' do
let(:feature_flag) { double(:feature_flag, name: 'test') }
it_behaves_like 'not found'
end
end
describe 'GET /projects/:id/feature_flags/:name/scopes/:environment_scope' do describe 'GET /projects/:id/feature_flags/:name/scopes/:environment_scope' do
subject do subject do
get api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes/#{environment_scope}", get api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes/#{environment_scope}",
...@@ -192,6 +242,52 @@ describe API::FeatureFlagScopes do ...@@ -192,6 +242,52 @@ describe API::FeatureFlagScopes do
end end
end end
describe 'PUT /projects/:id/feature_flags/:name/scopes/:environment_scope' do
subject do
put api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes/#{environment_scope}",
user), params: params
end
let(:environment_scope) { scope.environment_scope }
let(:params) do
{
active: true,
strategies: [{ name: 'userWithId', parameters: { 'userIds': 'a,b,c' } }].to_json
}
end
context 'when there is a corresponding feature flag' do
let!(:feature_flag) { create(:operations_feature_flag, project: project) }
let(:scope) { create_scope(feature_flag, 'staging', false, [{ name: "default", parameters: {} }]) }
it_behaves_like 'check user permission'
it 'returns the updated scope' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/feature_flag_scope', dir: 'ee')
expect(json_response['id']).to eq(scope.id)
expect(json_response['active']).to eq(params[:active])
expect(json_response['strategies']).to eq(JSON.parse(params[:strategies]))
end
context 'when there are no corresponding feature flag scopes' do
let(:scope) { double(:feature_flag_scope, environment_scope: 'prd') }
it_behaves_like 'not found'
end
end
context 'when there are no corresponding feature flags' do
let(:feature_flag) { double(:feature_flag, name: 'test') }
let(:scope) { double(:feature_flag_scope, environment_scope: 'prd') }
it_behaves_like 'not found'
end
end
describe 'DELETE /projects/:id/feature_flags/:name/scopes/:environment_scope' do describe 'DELETE /projects/:id/feature_flags/:name/scopes/:environment_scope' do
subject do subject do
delete api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes/#{environment_scope}", delete api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes/#{environment_scope}",
......
...@@ -43,6 +43,7 @@ describe FeatureFlags::UpdateService do ...@@ -43,6 +43,7 @@ describe FeatureFlags::UpdateService do
it 'returns error status' do it 'returns error status' do
expect(subject[:status]).to eq(:error) expect(subject[:status]).to eq(:error)
expect(subject[:http_status]).to eq(:bad_request)
end end
it 'returns error messages' do it 'returns error messages' 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