Skip to content

Commit

Permalink
Merge Cloud::Engine and Railtie
Browse files Browse the repository at this point in the history
  • Loading branch information
bkeepers committed Aug 1, 2023
1 parent bce4d4f commit daf4f7e
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 135 deletions.
2 changes: 1 addition & 1 deletion lib/flipper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,4 @@ def groups_registry=(registry)
require 'flipper/typecast'
require 'flipper/version'

require "flipper/railtie" if defined?(Rails::Railtie)
require "flipper/engine" if defined?(Rails)
10 changes: 3 additions & 7 deletions lib/flipper/cloud.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
require "flipper/cloud/configuration"
require "flipper/cloud/dsl"
require "flipper/cloud/middleware"
require "flipper/cloud/engine" if defined?(Rails::Engine)

module Flipper
module Cloud
Expand Down Expand Up @@ -40,13 +39,10 @@ def self.app(flipper = nil, options = {})

# Private: Configure Flipper to use Cloud by default
def self.set_default
Flipper.configure do |config|
config.default do
if ENV["FLIPPER_CLOUD_TOKEN"]
if ENV["FLIPPER_CLOUD_TOKEN"]
Flipper.configure do |config|
config.default do
self.new(local_adapter: config.adapter)
else
warn "Missing FLIPPER_CLOUD_TOKEN environment variable. Disabling Flipper::Cloud."
Flipper.new(config.adapter)
end
end
end
Expand Down
26 changes: 0 additions & 26 deletions lib/flipper/cloud/engine.rb

This file was deleted.

1 change: 1 addition & 0 deletions lib/flipper/cloud/routes.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Default routes loaded by Flipper::Cloud::Engine
Rails.application.routes.draw do
if ENV["FLIPPER_CLOUD_TOKEN"] && ENV["FLIPPER_CLOUD_SYNC_SECRET"]
require 'flipper/cloud'
config = Rails.application.config.flipper

cloud_app = Flipper::Cloud.app(nil,
Expand Down
22 changes: 19 additions & 3 deletions lib/flipper/railtie.rb → lib/flipper/engine.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
module Flipper
class Railtie < Rails::Railtie
class Engine < Rails::Engine
paths["config/routes.rb"] = ["lib/flipper/cloud/routes.rb"]

config.before_configuration do
config.flipper = ActiveSupport::OrderedOptions.new.update(
env_key: ENV.fetch('FLIPPER_ENV_KEY', 'flipper'),
memoize: ENV.fetch('FLIPPER_MEMOIZE', 'true').casecmp('true').zero?,
preload: ENV.fetch('FLIPPER_PRELOAD', 'true').casecmp('true').zero?,
instrumenter: ENV.fetch('FLIPPER_INSTRUMENTER', 'ActiveSupport::Notifications').constantize,
log: ENV.fetch('FLIPPER_LOG', 'true').casecmp('true').zero?
log: ENV.fetch('FLIPPER_LOG', 'true').casecmp('true').zero?,
cloud_path: "_flipper"
)
end

Expand All @@ -17,9 +20,18 @@ class Railtie < Rails::Railtie
end

initializer "flipper.default", before: :load_config_initializers do |app|
require 'flipper/cloud' if cloud?

Flipper.configure do |config|
config.default do
Flipper.new(config.adapter, instrumenter: app.config.flipper.instrumenter)
if cloud?
Flipper::Cloud.new(
local_adapter: config.adapter,
instrumenter: app.config.flipper.instrumenter
)
else
Flipper.new(config.adapter, instrumenter: app.config.flipper.instrumenter)
end
end
end
end
Expand All @@ -43,5 +55,9 @@ class Railtie < Rails::Railtie
}
end
end

def cloud?
!!ENV["FLIPPER_CLOUD_TOKEN"]
end
end
end
94 changes: 0 additions & 94 deletions spec/flipper/cloud/engine_spec.rb

This file was deleted.

86 changes: 82 additions & 4 deletions spec/flipper/railtie_spec.rb → spec/flipper/engine_spec.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
require 'rails'
require 'flipper/railtie'
require 'flipper/engine'

RSpec.describe Flipper::Railtie do
RSpec.describe Flipper::Engine do
let(:application) do
Class.new(Rails::Application).create(railties: [Flipper::Railtie]) do
Class.new(Rails::Application) do
config.eager_load = false
config.logger = ActiveSupport::Logger.new($stdout)
end
end

before do
Rails.application = nil
ActiveSupport::Dependencies.autoload_paths = ActiveSupport::Dependencies.autoload_paths.dup
ActiveSupport::Dependencies.autoload_once_paths = ActiveSupport::Dependencies.autoload_once_paths.dup
end
Expand All @@ -17,7 +19,7 @@

subject { application.initialize! }

describe 'initializers' do
context 'cloudless' do
it 'can set env_key from ENV' do
ENV['FLIPPER_ENV_KEY'] = 'flopper'

Expand Down Expand Up @@ -100,6 +102,82 @@
end
end

context 'with cloud' do
let(:env) do
{ "FLIPPER_CLOUD_TOKEN" => "test-token" }
end

# App for Rack::Test
let(:app) { application.routes }

it "initializes cloud configuration" do
stub_request(:get, /flippercloud\.io/).to_return(status: 200, body: "{}")

ENV.update(env)
application.initialize!

expect(Flipper.instance).to be_a(Flipper::Cloud::DSL)
expect(Flipper.instance.instrumenter).to be(ActiveSupport::Notifications)
end

context "with CLOUD_SYNC_SECRET" do
before do
env.update "FLIPPER_CLOUD_SYNC_SECRET" => "test-secret"
end

let(:request_body) do
JSON.generate({
"environment_id" => 1,
"webhook_id" => 1,
"delivery_id" => SecureRandom.uuid,
"action" => "sync",
})
end
let(:timestamp) { Time.now }
let(:signature) {
Flipper::Cloud::MessageVerifier.new(secret: env["FLIPPER_CLOUD_SYNC_SECRET"]).generate(request_body, timestamp)
}
let(:signature_header_value) {
Flipper::Cloud::MessageVerifier.new(secret: "").header(signature, timestamp)
}

it "configures webhook app" do
ENV.update(env)
application.initialize!

stub = stub_request(:get, "https://www.flippercloud.io/adapter/features?exclude_gate_names=true").with({
headers: { "Flipper-Cloud-Token" => ENV["FLIPPER_CLOUD_TOKEN"] },
}).to_return(status: 200, body: JSON.generate({ features: {} }), headers: {})

post "/_flipper", request_body, { "HTTP_FLIPPER_CLOUD_SIGNATURE" => signature_header_value }

expect(last_response.status).to eq(200)
expect(stub).to have_been_requested
end
end

context "without CLOUD_SYNC_SECRET" do
it "does not configure webhook app" do
ENV.update(env)
application.initialize!

post "/_flipper"
expect(last_response.status).to eq(404)
end
end

context "without FLIPPER_CLOUD_TOKEN" do
it "gracefully skips configuring webhook app" do
ENV["FLIPPER_CLOUD_TOKEN"] = nil
application.initialize!
expect(Flipper.instance).to be_a(Flipper::DSL)

post "/_flipper"
expect(last_response.status).to eq(404)
end
end
end

# Add app initializer in the same order as config/initializers/*
def initializer(&block)
application.initializer 'spec', before: :load_config_initializers do
Expand Down

0 comments on commit daf4f7e

Please sign in to comment.