Skip to content

Commit

Permalink
Merge pull request #179 from jnunemaker/api-v1-percentage-of-actors-gate
Browse files Browse the repository at this point in the history
Api V1 percentage_of_actors gate endpoint
  • Loading branch information
AlexWheeler authored Oct 24, 2016
2 parents d6f57a4 + 2dadf41 commit 43cc964
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/flipper/api/error_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def as_json
ERRORS = {
feature_not_found: Error.new(1, "Feature not found.", "", 404),
group_not_registered: Error.new(2, "Group not registered.", "", 404),
percentage_invalid: Error.new(3, "Percentage must be a positive number less than or equal to 100.", "", 400),
}
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/flipper/api/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def initialize(app, flipper_or_block)
end

@action_collection = ActionCollection.new
@action_collection.add Api::V1::Actions::PercentageOfActorsGate
@action_collection.add Api::V1::Actions::GroupsGate
@action_collection.add Api::V1::Actions::BooleanGate
@action_collection.add Api::V1::Actions::Feature
Expand Down
57 changes: 57 additions & 0 deletions lib/flipper/api/v1/actions/percentage_of_actors_gate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require 'flipper/api/action'
require 'flipper/api/v1/decorators/feature'

module Flipper
module Api
module V1
module Actions
class PercentageOfActorsGate < Api::Action
route %r{api/v1/features/[^/]*/percentage_of_actors/?\Z}

def post
ensure_valid_enable_params
feature = flipper[feature_name]
feature.enable_percentage_of_actors(percentage)
decorated_feature = Decorators::Feature.new(feature)
json_response(decorated_feature.as_json, 200)
end

def delete
ensure_valid_disable_params
feature = flipper[feature_name]
feature.disable_percentage_of_actors
decorated_feature = Decorators::Feature.new(feature)
json_response(decorated_feature.as_json, 200)
end

private

def ensure_valid_enable_params
json_error_response(:feature_not_found) unless feature_names.include?(feature_name)
json_error_response(:percentage_invalid) unless percentage >= 0 && percentage <= 100
end

def ensure_valid_disable_params
json_error_response(:feature_not_found) unless feature_names.include?(feature_name)
end

def feature_name
@feature_name ||= Rack::Utils.unescape(path_parts[-2])
end

def percentage
@percentage ||= begin
Integer(params['percentage'])
rescue ArgumentError, TypeError
-1
end
end

def feature_names
@feature_names ||= flipper.adapter.features
end
end
end
end
end
end
85 changes: 85 additions & 0 deletions spec/flipper/api/v1/actions/percentage_of_actors_gate_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
require 'helper'

RSpec.describe Flipper::Api::V1::Actions::PercentageOfActorsGate do
let(:app) { build_api(flipper) }

describe 'enable' do
before do
flipper[:my_feature].disable
post '/api/v1/features/my_feature/percentage_of_actors', { percentage: '10' }
end

it 'enables gate for feature' do
expect(flipper[:my_feature].enabled_gate_names).to include(:percentage_of_actors)
end

it 'returns decorated feature with gate enabled for 10 percent of actors' do
gate = json_response['gates'].find { |gate| gate['name'] == 'percentage_of_actors' }
expect(gate['value']).to eq(10)
end

end

describe 'disable' do
before do
flipper[:my_feature].disable
delete '/api/v1/features/my_feature/percentage_of_actors'
end

it 'disables gate for feature' do
expect(flipper[:my_feature].enabled_gates).to be_empty
end

it 'returns decorated feature with gate disabled' do
gate = json_response['gates'].find { |gate| gate['name'] == 'percentage_of_actors' }
expect(gate['value']).to eq(0)
end
end

describe 'non-existent feature' do
before do
delete '/api/v1/features/my_feature/percentage_of_actors'
end

it '404s with correct error response when feature does not exist' do
expect(last_response.status).to eq(404)
expect(json_response).to eq({ 'code' => 1, 'message' => 'Feature not found.', 'more_info' => '' })
end
end

describe 'out of range parameter percentage parameter' do
before do
flipper[:my_feature].disable
post '/api/v1/features/my_feature/percentage_of_actors', { percentage: '300' }
end

it '400s with correct error response when percentage parameter is invalid' do
expect(last_response.status).to eq(400)
expect(json_response).to eq({ 'code' => 3, 'message' => 'Percentage must be a positive number less than or equal to 100.', 'more_info' => '' })
end
end

describe 'percentage parameter not an integer' do
before do
flipper[:my_feature].disable
post '/api/v1/features/my_feature/percentage_of_actors', { percentage: 'foo' }
end

it '400s with correct error response when percentage parameter is invalid' do
expect(last_response.status).to eq(400)
expect(json_response).to eq({ 'code' => 3, 'message' => 'Percentage must be a positive number less than or equal to 100.', 'more_info' => '' })
end
end

describe 'missing percentage parameter' do
before do
flipper[:my_feature].disable
post '/api/v1/features/my_feature/percentage_of_actors'
end

it '400s with correct error response when percentage parameter is missing' do
expect(last_response.status).to eq(400)
expect(json_response).to eq({ 'code' => 3, 'message' => 'Percentage must be a positive number less than or equal to 100.', 'more_info' => '' })
end
end
end

0 comments on commit 43cc964

Please sign in to comment.