Skip to content

Commit

Permalink
Merge pull request #259 from jnunemaker/env-key
Browse files Browse the repository at this point in the history
Allow setting env key for all middleware
  • Loading branch information
jnunemaker authored May 16, 2017
2 parents 89a640f + af530e7 commit a540f07
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 19 deletions.
9 changes: 5 additions & 4 deletions lib/flipper/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ module Flipper
module Api
CONTENT_TYPE = 'application/json'.freeze

def self.app(flipper = nil)
def self.app(flipper = nil, options = {})
env_key = options.fetch(:env_key, 'flipper')
app = ->(_) { [404, { 'Content-Type'.freeze => CONTENT_TYPE }, ['{}'.freeze]] }
builder = Rack::Builder.new
yield builder if block_given?
builder.use Flipper::Middleware::SetupEnv, flipper
builder.use Flipper::Middleware::Memoizer
builder.use Flipper::Api::JsonParams
builder.use Flipper::Api::Middleware
builder.use Flipper::Middleware::SetupEnv, flipper, env_key: env_key
builder.use Flipper::Middleware::Memoizer, env_key: env_key
builder.use Flipper::Api::Middleware, env_key: env_key
builder.run app
klass = self
builder.define_singleton_method(:inspect) { klass.inspect } # pretty rake routes output
Expand Down
5 changes: 3 additions & 2 deletions lib/flipper/api/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
module Flipper
module Api
class Middleware
def initialize(app)
def initialize(app, options = {})
@app = app
@env_key = options.fetch(:env_key, 'flipper')

@action_collection = ActionCollection.new
@action_collection.add Api::V1::Actions::PercentageOfTimeGate
Expand All @@ -33,7 +34,7 @@ def call!(env)
if action_class.nil?
@app.call(env)
else
flipper = env.fetch('flipper')
flipper = env.fetch(@env_key)
action_class.run(flipper, request)
end
end
Expand Down
3 changes: 3 additions & 0 deletions lib/flipper/cloud.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def self.new(token, options = {})
headers: {
"Feature-Flipper-Token" => token,
},
read_timeout: options[:read_timeout],
open_timeout: options[:open_timeout],
debug_output: options[:debug_output],
}
adapter = Flipper::Adapters::Http.new(http_options)

Expand Down
3 changes: 2 additions & 1 deletion lib/flipper/middleware/memoizer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def initialize(app, opts = {})

@app = app
@opts = opts
@env_key = opts.fetch(:env_key, 'flipper')
end

def call(env)
Expand All @@ -48,7 +49,7 @@ def skip_memoize?(request)
end

def memoized_call(env)
flipper = env.fetch('flipper')
flipper = env.fetch(@env_key)
original = flipper.adapter.memoizing?
flipper.adapter.memoize = true

Expand Down
5 changes: 3 additions & 2 deletions lib/flipper/middleware/setup_env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ class SetupEnv
# # using with a block that yields a flipper instance
# use Flipper::Middleware::SetEnv, lambda { Flipper.new(...) }
#
def initialize(app, flipper_or_block)
def initialize(app, flipper_or_block, options = {})
@app = app
@env_key = options.fetch(:env_key, 'flipper')

if flipper_or_block.respond_to?(:call)
@flipper_block = flipper_or_block
Expand All @@ -30,7 +31,7 @@ def initialize(app, flipper_or_block)
end

def call(env)
env['flipper'.freeze] ||= flipper
env[@env_key] ||= flipper
@app.call(env)
end

Expand Down
9 changes: 5 additions & 4 deletions lib/flipper/ui.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,17 @@ def self.root
@root ||= Pathname(__FILE__).dirname.expand_path.join('ui')
end

def self.app(flipper = nil)
def self.app(flipper = nil, options = {})
env_key = options.fetch(:env_key, 'flipper')
app = ->() { [200, { 'Content-Type' => 'text/html' }, ['']] }
builder = Rack::Builder.new
yield builder if block_given?
builder.use Rack::Protection
builder.use Rack::Protection::AuthenticityToken
builder.use Rack::MethodOverride
builder.use Flipper::Middleware::SetupEnv, flipper
builder.use Flipper::Middleware::Memoizer
builder.use Middleware
builder.use Flipper::Middleware::SetupEnv, flipper, env_key: env_key
builder.use Flipper::Middleware::Memoizer, env_key: env_key
builder.use Middleware, env_key: env_key
builder.run app
klass = self
builder.define_singleton_method(:inspect) { klass.inspect } # pretty rake routes output
Expand Down
5 changes: 3 additions & 2 deletions lib/flipper/ui/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
module Flipper
module UI
class Middleware
def initialize(app)
def initialize(app, options = {})
@app = app
@env_key = options.fetch(:env_key, 'flipper')

@action_collection = ActionCollection.new

Expand Down Expand Up @@ -43,7 +44,7 @@ def call!(env)
if action_class.nil?
@app.call(env)
else
flipper = env.fetch('flipper')
flipper = env.fetch(@env_key)
action_class.run(flipper, request)
end
end
Expand Down
24 changes: 24 additions & 0 deletions spec/flipper/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,30 @@
end
end

context 'when initialized with env_key' do
let(:app) { build_api(flipper, env_key: 'flipper_api') }

it 'uses provided env key instead of default' do
flipper[:a].enable
flipper[:b].disable

default_env_flipper = build_flipper
default_env_flipper[:env_a].enable
default_env_flipper[:env_b].disable

params = {}
env = {
'flipper' => default_env_flipper,
'flipper_api' => flipper,
}
get '/features', params, env

expect(last_response.status).to eq(200)
feature_names = json_response.fetch('features').map { |feature| feature.fetch('key') }
expect(feature_names).to eq(%w(a b))
end
end

context "when request does not match any api routes" do
let(:app) { build_api(flipper) }

Expand Down
18 changes: 18 additions & 0 deletions spec/flipper/cloud_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,22 @@
# instance.adapter is memoizable adapter instance
expect(instance.adapter.adapter).to be_instance_of(Flipper::Adapters::Instrumented)
end

it 'can set debug_output' do
expect(Flipper::Adapters::Http::Client).to receive(:new)
.with(hash_including(debug_output: STDOUT))
described_class.new('asdf', debug_output: STDOUT)
end

it 'can set read_timeout' do
expect(Flipper::Adapters::Http::Client).to receive(:new)
.with(hash_including(read_timeout: 1))
described_class.new('asdf', read_timeout: 1)
end

it 'can set open_timeout' do
expect(Flipper::Adapters::Http::Client).to receive(:new)
.with(hash_including(open_timeout: 1))
described_class.new('asdf', open_timeout: 1)
end
end
8 changes: 4 additions & 4 deletions spec/support/spec_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ def self.included(base)
base.let(:app) { build_app(flipper) }
end

def build_app(flipper)
Flipper::UI.app(flipper) do |builder|
def build_app(flipper, options = {})
Flipper::UI.app(flipper, options) do |builder|
builder.use Rack::Session::Cookie, secret: 'test'
end
end

def build_api(flipper)
Flipper::Api.app(flipper)
def build_api(flipper, options = {})
Flipper::Api.app(flipper, options)
end

def build_flipper(adapter = build_memory_adapter)
Expand Down

0 comments on commit a540f07

Please sign in to comment.