1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
require 'flipper/cloud'
require 'flipper/adapters/instrumented'
require 'flipper/instrumenters/memory'
RSpec.describe Flipper::Cloud do
before do
stub_request(:get, /flippercloud\.io/).to_return(status: 200, body: "{}")
end
context "initialize with token" do
let(:token) { 'asdf' }
before do
@instance = described_class.new(token: token)
end
it 'returns Flipper::DSL instance' do
expect(@instance).to be_instance_of(Flipper::Cloud::DSL)
end
it 'can read the cloud configuration' do
expect(@instance.cloud_configuration).to be_instance_of(Flipper::Cloud::Configuration)
end
it 'configures the correct adapter' do
# pardon the nesting...
memoized_adapter = @instance.adapter
poll_adapter = memoized_adapter.adapter
dual_write_adapter = poll_adapter.adapter
expect(poll_adapter).to be_instance_of(Flipper::Adapters::Poll)
expect(dual_write_adapter).to be_instance_of(Flipper::Adapters::DualWrite)
http_adapter = dual_write_adapter.remote
client = http_adapter.client
expect(client.uri.scheme).to eq('https')
expect(client.uri.host).to eq('www.flippercloud.io')
expect(client.uri.path).to eq('/adapter')
expect(client.headers['Flipper-Cloud-Token']).to eq(token)
expect(@instance.instrumenter).to be(Flipper::Instrumenters::Noop)
end
end
context 'initialize with token and options' do
it 'sets correct url' do
@instance = described_class.new(token: 'asdf', url: 'https://www.fakeflipper.com/sadpanda')
uri = @instance.adapter.adapter.adapter.remote.client.uri
expect(uri.scheme).to eq('https')
expect(uri.host).to eq('www.fakeflipper.com')
expect(uri.path).to eq('/sadpanda')
end
end
it 'can initialize with no token explicitly provided' do
ENV['FLIPPER_CLOUD_TOKEN'] = 'asdf'
expect(described_class.new).to be_instance_of(Flipper::Cloud::DSL)
end
it 'can set instrumenter' do
instrumenter = Flipper::Instrumenters::Memory.new
instance = described_class.new(token: 'asdf', instrumenter: instrumenter)
expect(instance.instrumenter).to be(instrumenter)
end
it 'allows wrapping adapter with another adapter like the instrumenter' do
instance = described_class.new(token: 'asdf') do |config|
config.adapter do |adapter|
Flipper::Adapters::Instrumented.new(adapter)
end
end
# 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)).at_least(:once)
described_class.new(token: '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)).at_least(:once)
described_class.new(token: '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)).at_least(:once)
described_class.new(token: 'asdf', open_timeout: 1)
end
if RUBY_VERSION >= '2.6.0'
it 'can set write_timeout' do
expect(Flipper::Adapters::Http::Client).to receive(:new)
.with(hash_including(open_timeout: 1)).at_least(:once)
described_class.new(token: 'asdf', open_timeout: 1)
end
end
it 'can import' do
stub_request(:post, /www\.flippercloud\.io\/adapter\/features.*/).
with(headers: {'Flipper-Cloud-Token'=>'asdf'}).to_return(status: 200, body: "{}", headers: {})
flipper = Flipper.new(Flipper::Adapters::Memory.new)
flipper.enable(:test)
flipper.enable(:search)
flipper.enable_actor(:stats, Flipper::Actor.new("jnunemaker"))
flipper.enable_percentage_of_time(:logging, 5)
cloud_flipper = Flipper::Cloud.new(token: "asdf")
get_all = {
"logging" => {actors: Set.new, boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: "5"},
"search" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
"stats" => {actors: Set["jnunemaker"], boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
"test" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
}
expect(flipper.adapter.get_all).to eq(get_all)
cloud_flipper.import(flipper)
expect(flipper.adapter.get_all).to eq(get_all)
expect(cloud_flipper.adapter.get_all).to eq(get_all)
end
it 'raises error for failure while importing' do
stub_request(:post, /www\.flippercloud\.io\/adapter\/features.*/).
with(headers: {'Flipper-Cloud-Token'=>'asdf'}).to_return(status: 500, body: "{}")
flipper = Flipper.new(Flipper::Adapters::Memory.new)
flipper.enable(:test)
flipper.enable(:search)
flipper.enable_actor(:stats, Flipper::Actor.new("jnunemaker"))
flipper.enable_percentage_of_time(:logging, 5)
cloud_flipper = Flipper::Cloud.new(token: "asdf")
get_all = {
"logging" => {actors: Set.new, boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: "5"},
"search" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
"stats" => {actors: Set["jnunemaker"], boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
"test" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
}
expect(flipper.adapter.get_all).to eq(get_all)
expect { cloud_flipper.import(flipper) }.to raise_error(Flipper::Adapters::Http::Error)
expect(flipper.adapter.get_all).to eq(get_all)
end
it 'raises error for timeout while importing' do
stub_request(:post, /www\.flippercloud\.io\/adapter\/features.*/).
with(headers: {'Flipper-Cloud-Token'=>'asdf'}).to_timeout
flipper = Flipper.new(Flipper::Adapters::Memory.new)
flipper.enable(:test)
flipper.enable(:search)
flipper.enable_actor(:stats, Flipper::Actor.new("jnunemaker"))
flipper.enable_percentage_of_time(:logging, 5)
cloud_flipper = Flipper::Cloud.new(token: "asdf")
get_all = {
"logging" => {actors: Set.new, boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: "5"},
"search" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
"stats" => {actors: Set["jnunemaker"], boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
"test" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
}
expect(flipper.adapter.get_all).to eq(get_all)
expect { cloud_flipper.import(flipper) }.to raise_error(Net::OpenTimeout)
expect(flipper.adapter.get_all).to eq(get_all)
end
end
|