flipper-ui 0.10.2 → 0.11.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/flipper-ui.gemspec +12 -12
  3. data/lib/flipper/ui.rb +6 -4
  4. data/lib/flipper/ui/action.rb +22 -21
  5. data/lib/flipper/ui/action_collection.rb +2 -2
  6. data/lib/flipper/ui/actions/actors_gate.rb +7 -7
  7. data/lib/flipper/ui/actions/add_feature.rb +6 -6
  8. data/lib/flipper/ui/actions/boolean_gate.rb +2 -2
  9. data/lib/flipper/ui/actions/feature.rb +5 -6
  10. data/lib/flipper/ui/actions/features.rb +9 -10
  11. data/lib/flipper/ui/actions/file.rb +0 -1
  12. data/lib/flipper/ui/actions/gate.rb +5 -2
  13. data/lib/flipper/ui/actions/groups_gate.rb +16 -14
  14. data/lib/flipper/ui/actions/home.rb +1 -2
  15. data/lib/flipper/ui/actions/percentage_of_actors_gate.rb +2 -2
  16. data/lib/flipper/ui/actions/percentage_of_time_gate.rb +2 -2
  17. data/lib/flipper/ui/decorators/feature.rb +9 -9
  18. data/lib/flipper/ui/decorators/gate.rb +7 -6
  19. data/lib/flipper/ui/middleware.rb +2 -27
  20. data/lib/flipper/ui/util.rb +2 -2
  21. data/lib/flipper/version.rb +1 -1
  22. data/spec/flipper/ui/action_spec.rb +22 -22
  23. data/spec/flipper/ui/actions/actors_gate_spec.rb +49 -45
  24. data/spec/flipper/ui/actions/add_feature_spec.rb +9 -9
  25. data/spec/flipper/ui/actions/boolean_gate_spec.rb +22 -22
  26. data/spec/flipper/ui/actions/feature_spec.rb +34 -34
  27. data/spec/flipper/ui/actions/features_spec.rb +44 -40
  28. data/spec/flipper/ui/actions/file_spec.rb +8 -8
  29. data/spec/flipper/ui/actions/gate_spec.rb +17 -15
  30. data/spec/flipper/ui/actions/groups_gate_spec.rb +57 -50
  31. data/spec/flipper/ui/actions/home_spec.rb +4 -4
  32. data/spec/flipper/ui/actions/percentage_of_actors_gate_spec.rb +24 -22
  33. data/spec/flipper/ui/actions/percentage_of_time_gate_spec.rb +24 -22
  34. data/spec/flipper/ui/decorators/feature_spec.rb +27 -27
  35. data/spec/flipper/ui/decorators/gate_spec.rb +10 -10
  36. data/spec/flipper/ui/util_spec.rb +4 -4
  37. data/spec/flipper/ui_spec.rb +58 -59
  38. metadata +7 -7
@@ -23,20 +23,20 @@ module Flipper
23
23
  'id' => name.to_s,
24
24
  'name' => pretty_name,
25
25
  'state' => state.to_s,
26
- 'gates' => gates.map { |gate|
26
+ 'gates' => gates.map do |gate|
27
27
  Decorators::Gate.new(gate, gate_values[gate.key]).as_json
28
- },
28
+ end,
29
29
  }
30
30
  end
31
31
 
32
32
  def color_class
33
33
  case feature.state
34
34
  when :on
35
- "text-open"
35
+ 'text-open'
36
36
  when :off
37
- "text-closed"
37
+ 'text-closed'
38
38
  when :conditional
39
- "text-pending"
39
+ 'text-pending'
40
40
  end
41
41
  end
42
42
 
@@ -45,10 +45,10 @@ module Flipper
45
45
  end
46
46
 
47
47
  StateSortMap = {
48
- :on => 1,
49
- :conditional => 2,
50
- :off => 3,
51
- }
48
+ on: 1,
49
+ conditional: 2,
50
+ off: 3,
51
+ }.freeze
52
52
 
53
53
  def <=>(other)
54
54
  if state == other.state
@@ -17,12 +17,13 @@ module Flipper
17
17
 
18
18
  # Public: Returns instance as hash that is ready to be json dumped.
19
19
  def as_json
20
- value_as_json = case data_type
21
- when :set
22
- value.to_a # json doesn't like sets
23
- else
24
- value
25
- end
20
+ value_as_json =
21
+ case data_type
22
+ when :set
23
+ value.to_a # json doesn't like sets
24
+ else
25
+ value
26
+ end
26
27
 
27
28
  {
28
29
  'key' => gate.key.to_s,
@@ -9,31 +9,9 @@ end
9
9
  module Flipper
10
10
  module UI
11
11
  class Middleware
12
- # Public: Initializes an instance of the UI middleware.
13
- #
14
- # app - The app this middleware is included in.
15
- # flipper_or_block - The Flipper::DSL instance or a block that yields a
16
- # Flipper::DSL instance to use for all operations.
17
- #
18
- # Examples
19
- #
20
- # flipper = Flipper.new(...)
21
- #
22
- # # using with a normal flipper instance
23
- # use Flipper::UI::Middleware, flipper
24
- #
25
- # # using with a block that yields a flipper instance
26
- # use Flipper::UI::Middleware, lambda { Flipper.new(...) }
27
- #
28
- def initialize(app, flipper_or_block)
12
+ def initialize(app)
29
13
  @app = app
30
14
 
31
- if flipper_or_block.respond_to?(:call)
32
- @flipper_block = flipper_or_block
33
- else
34
- @flipper = flipper_or_block
35
- end
36
-
37
15
  @action_collection = ActionCollection.new
38
16
 
39
17
  # UI
@@ -54,10 +32,6 @@ module Flipper
54
32
  @action_collection.add UI::Actions::Home
55
33
  end
56
34
 
57
- def flipper
58
- @flipper ||= @flipper_block.call
59
- end
60
-
61
35
  def call(env)
62
36
  dup.call!(env)
63
37
  end
@@ -69,6 +43,7 @@ module Flipper
69
43
  if action_class.nil?
70
44
  @app.call(env)
71
45
  else
46
+ flipper = env.fetch('flipper')
72
47
  action_class.run(flipper, request)
73
48
  end
74
49
  end
@@ -2,14 +2,14 @@ module Flipper
2
2
  module UI
3
3
  module Util
4
4
  # Private: 0x3000: fullwidth whitespace
5
- NON_WHITESPACE_REGEXP = %r![^\s#{[0x3000].pack("U")}]!
5
+ NON_WHITESPACE_REGEXP = /[^\s#{[0x3000].pack("U")}]/
6
6
 
7
7
  def self.blank?(str)
8
8
  str.to_s !~ NON_WHITESPACE_REGEXP
9
9
  end
10
10
 
11
11
  def self.titleize(str)
12
- str.to_s.split("_").map { |word| word.capitalize }.join(" ")
12
+ str.to_s.split('_').map(&:capitalize).join(' ')
13
13
  end
14
14
  end
15
15
  end
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = "0.10.2".freeze
2
+ VERSION = '0.11.0.beta1'.freeze
3
3
  end
@@ -1,59 +1,59 @@
1
1
  require 'helper'
2
2
 
3
3
  RSpec.describe Flipper::UI::Action do
4
- let(:action_subclass) {
4
+ let(:action_subclass) do
5
5
  Class.new(described_class) do
6
6
  def noooope
7
- raise "should never run this"
7
+ raise 'should never run this'
8
8
  end
9
9
 
10
10
  def get
11
- [200, {}, "get"]
11
+ [200, {}, 'get']
12
12
  end
13
13
 
14
14
  def post
15
- [200, {}, "post"]
15
+ [200, {}, 'post']
16
16
  end
17
17
 
18
18
  def put
19
- [200, {}, "put"]
19
+ [200, {}, 'put']
20
20
  end
21
21
 
22
22
  def delete
23
- [200, {}, "delete"]
23
+ [200, {}, 'delete']
24
24
  end
25
25
  end
26
- }
26
+ end
27
27
 
28
28
  it "won't run method that isn't whitelisted" do
29
- fake_request = Struct.new(:request_method, :env, :session).new("NOOOOPE", {}, {})
29
+ fake_request = Struct.new(:request_method, :env, :session).new('NOOOOPE', {}, {})
30
30
  action = action_subclass.new(flipper, fake_request)
31
- expect {
31
+ expect do
32
32
  action.run
33
- }.to raise_error(Flipper::UI::RequestMethodNotSupported)
33
+ end.to raise_error(Flipper::UI::RequestMethodNotSupported)
34
34
  end
35
35
 
36
- it "will run get" do
37
- fake_request = Struct.new(:request_method, :env, :session).new("GET", {}, {})
36
+ it 'will run get' do
37
+ fake_request = Struct.new(:request_method, :env, :session).new('GET', {}, {})
38
38
  action = action_subclass.new(flipper, fake_request)
39
- expect(action.run).to eq([200, {}, "get"])
39
+ expect(action.run).to eq([200, {}, 'get'])
40
40
  end
41
41
 
42
- it "will run post" do
43
- fake_request = Struct.new(:request_method, :env, :session).new("POST", {}, {})
42
+ it 'will run post' do
43
+ fake_request = Struct.new(:request_method, :env, :session).new('POST', {}, {})
44
44
  action = action_subclass.new(flipper, fake_request)
45
- expect(action.run).to eq([200, {}, "post"])
45
+ expect(action.run).to eq([200, {}, 'post'])
46
46
  end
47
47
 
48
- it "will run put" do
49
- fake_request = Struct.new(:request_method, :env, :session).new("PUT", {}, {})
48
+ it 'will run put' do
49
+ fake_request = Struct.new(:request_method, :env, :session).new('PUT', {}, {})
50
50
  action = action_subclass.new(flipper, fake_request)
51
- expect(action.run).to eq([200, {}, "put"])
51
+ expect(action.run).to eq([200, {}, 'put'])
52
52
  end
53
53
 
54
- it "will run delete" do
55
- fake_request = Struct.new(:request_method, :env, :session).new("DELETE", {}, {})
54
+ it 'will run delete' do
55
+ fake_request = Struct.new(:request_method, :env, :session).new('DELETE', {}, {})
56
56
  action = action_subclass.new(flipper, fake_request)
57
- expect(action.run).to eq([200, {}, "delete"])
57
+ expect(action.run).to eq([200, {}, 'delete'])
58
58
  end
59
59
  end
@@ -1,107 +1,111 @@
1
1
  require 'helper'
2
2
 
3
3
  RSpec.describe Flipper::UI::Actions::ActorsGate do
4
- let(:token) {
4
+ let(:token) do
5
5
  if Rack::Protection::AuthenticityToken.respond_to?(:random_token)
6
6
  Rack::Protection::AuthenticityToken.random_token
7
7
  else
8
- "a"
8
+ 'a'
9
9
  end
10
- }
11
- let(:session) {
10
+ end
11
+ let(:session) do
12
12
  if Rack::Protection::AuthenticityToken.respond_to?(:random_token)
13
- {:csrf => token}
13
+ { csrf: token }
14
14
  else
15
- {"_csrf_token" => token}
15
+ { '_csrf_token' => token }
16
16
  end
17
- }
17
+ end
18
18
 
19
- describe "GET /features/:feature/actors" do
19
+ describe 'GET /features/:feature/actors' do
20
20
  before do
21
- get "features/search/actors"
21
+ get 'features/search/actors'
22
22
  end
23
23
 
24
- it "responds with success" do
24
+ it 'responds with success' do
25
25
  expect(last_response.status).to be(200)
26
26
  end
27
27
 
28
- it "renders add new actor form" do
28
+ it 'renders add new actor form' do
29
29
  expect(last_response.body).to include('<form action="/features/search/actors" method="post">')
30
30
  end
31
31
  end
32
32
 
33
- describe "POST /features/:feature/actors" do
34
- context "enabling an actor" do
35
- let(:value) { "User:6" }
33
+ describe 'POST /features/:feature/actors' do
34
+ context 'enabling an actor' do
35
+ let(:value) { 'User:6' }
36
36
 
37
37
  before do
38
- post "features/search/actors",
39
- {"value" => value, "operation" => "enable", "authenticity_token" => token},
40
- "rack.session" => session
38
+ post 'features/search/actors',
39
+ { 'value' => value, 'operation' => 'enable', 'authenticity_token' => token },
40
+ 'rack.session' => session
41
41
  end
42
42
 
43
- it "adds item to members" do
44
- expect(flipper[:search].actors_value).to include("User:6")
43
+ it 'adds item to members' do
44
+ expect(flipper[:search].actors_value).to include('User:6')
45
45
  end
46
46
 
47
- it "redirects back to feature" do
47
+ it 'redirects back to feature' do
48
48
  expect(last_response.status).to be(302)
49
- expect(last_response.headers["Location"]).to eq("/features/search")
49
+ expect(last_response.headers['Location']).to eq('/features/search')
50
50
  end
51
51
 
52
52
  context 'value contains whitespace' do
53
- let(:value) { " User:6 " }
53
+ let(:value) { ' User:6 ' }
54
54
 
55
- it "adds item without whitespace" do
56
- expect(flipper[:search].actors_value).to include("User:6")
55
+ it 'adds item without whitespace' do
56
+ expect(flipper[:search].actors_value).to include('User:6')
57
57
  end
58
58
  end
59
59
 
60
- context "for an invalid actor value" do
61
- context "empty value" do
62
- let(:value) { "" }
60
+ context 'for an invalid actor value' do
61
+ context 'empty value' do
62
+ let(:value) { '' }
63
63
 
64
- it "redirects back to feature" do
64
+ # rubocop:disable Metrics/LineLength
65
+ it 'redirects back to feature' do
65
66
  expect(last_response.status).to be(302)
66
- expect(last_response.headers["Location"]).to eq("/features/search/actors?error=%22%22+is+not+a+valid+actor+value.")
67
+ expect(last_response.headers['Location']).to eq('/features/search/actors?error=%22%22+is+not+a+valid+actor+value.')
67
68
  end
69
+ # rubocop:enable Metrics/LineLength
68
70
  end
69
71
 
70
- context "nil value" do
72
+ context 'nil value' do
71
73
  let(:value) { nil }
72
74
 
73
- it "redirects back to feature" do
75
+ # rubocop:disable Metrics/LineLength
76
+ it 'redirects back to feature' do
74
77
  expect(last_response.status).to be(302)
75
- expect(last_response.headers["Location"]).to eq("/features/search/actors?error=%22%22+is+not+a+valid+actor+value.")
78
+ expect(last_response.headers['Location']).to eq('/features/search/actors?error=%22%22+is+not+a+valid+actor+value.')
76
79
  end
80
+ # rubocop:enable Metrics/LineLength
77
81
  end
78
82
  end
79
83
  end
80
84
 
81
- context "disabling an actor" do
82
- let(:value) { "User:6" }
85
+ context 'disabling an actor' do
86
+ let(:value) { 'User:6' }
83
87
 
84
88
  before do
85
- flipper[:search].enable_actor Flipper::UI::Actor.new("User:6")
86
- post "features/search/actors",
87
- {"value" => value, "operation" => "disable", "authenticity_token" => token},
88
- "rack.session" => session
89
+ flipper[:search].enable_actor Flipper::UI::Actor.new('User:6')
90
+ post 'features/search/actors',
91
+ { 'value' => value, 'operation' => 'disable', 'authenticity_token' => token },
92
+ 'rack.session' => session
89
93
  end
90
94
 
91
- it "removes item from members" do
92
- expect(flipper[:search].actors_value).not_to include("User:6")
95
+ it 'removes item from members' do
96
+ expect(flipper[:search].actors_value).not_to include('User:6')
93
97
  end
94
98
 
95
- it "redirects back to feature" do
99
+ it 'redirects back to feature' do
96
100
  expect(last_response.status).to be(302)
97
- expect(last_response.headers["Location"]).to eq("/features/search")
101
+ expect(last_response.headers['Location']).to eq('/features/search')
98
102
  end
99
103
 
100
104
  context 'value contains whitespace' do
101
- let(:value) { " User:6 " }
105
+ let(:value) { ' User:6 ' }
102
106
 
103
- it "removes item whitout whitespace" do
104
- expect(flipper[:search].actors_value).not_to include("User:6")
107
+ it 'removes item whitout whitespace' do
108
+ expect(flipper[:search].actors_value).not_to include('User:6')
105
109
  end
106
110
  end
107
111
  end
@@ -1,43 +1,43 @@
1
1
  require 'helper'
2
2
 
3
3
  RSpec.describe Flipper::UI::Actions::AddFeature do
4
- describe "GET /features/new with feature_creation_enabled set to true" do
4
+ describe 'GET /features/new with feature_creation_enabled set to true' do
5
5
  before do
6
6
  @original_feature_creation_enabled = Flipper::UI.feature_creation_enabled
7
7
  Flipper::UI.feature_creation_enabled = true
8
- get "/features/new"
8
+ get '/features/new'
9
9
  end
10
10
 
11
11
  after do
12
12
  Flipper::UI.feature_creation_enabled = @original_feature_creation_enabled
13
13
  end
14
14
 
15
- it "responds with success" do
15
+ it 'responds with success' do
16
16
  expect(last_response.status).to be(200)
17
17
  end
18
18
 
19
- it "renders template" do
19
+ it 'renders template' do
20
20
  expect(last_response.body).to include('<form action="/features" method="post">')
21
21
  end
22
22
  end
23
23
 
24
- describe "GET /features/new with feature_creation_enabled set to false" do
24
+ describe 'GET /features/new with feature_creation_enabled set to false' do
25
25
  before do
26
26
  @original_feature_creation_enabled = Flipper::UI.feature_creation_enabled
27
27
  Flipper::UI.feature_creation_enabled = false
28
- get "/features/new"
28
+ get '/features/new'
29
29
  end
30
30
 
31
31
  after do
32
32
  Flipper::UI.feature_creation_enabled = @original_feature_creation_enabled
33
33
  end
34
34
 
35
- it "returns 403" do
35
+ it 'returns 403' do
36
36
  expect(last_response.status).to be(403)
37
37
  end
38
38
 
39
- it "renders feature creation disabled template" do
40
- expect(last_response.body).to include("Feature creation is disabled.")
39
+ it 'renders feature creation disabled template' do
40
+ expect(last_response.body).to include('Feature creation is disabled.')
41
41
  end
42
42
  end
43
43
  end
@@ -1,55 +1,55 @@
1
1
  require 'helper'
2
2
 
3
3
  RSpec.describe Flipper::UI::Actions::BooleanGate do
4
- let(:token) {
4
+ let(:token) do
5
5
  if Rack::Protection::AuthenticityToken.respond_to?(:random_token)
6
6
  Rack::Protection::AuthenticityToken.random_token
7
7
  else
8
- "a"
8
+ 'a'
9
9
  end
10
- }
11
- let(:session) {
10
+ end
11
+ let(:session) do
12
12
  if Rack::Protection::AuthenticityToken.respond_to?(:random_token)
13
- {:csrf => token}
13
+ { csrf: token }
14
14
  else
15
- {"_csrf_token" => token}
15
+ { '_csrf_token' => token }
16
16
  end
17
- }
17
+ end
18
18
 
19
- describe "POST /features/:feature/boolean" do
20
- context "with enable" do
19
+ describe 'POST /features/:feature/boolean' do
20
+ context 'with enable' do
21
21
  before do
22
22
  flipper.disable :search
23
- post "features/search/boolean",
24
- {"action" => "Enable", "authenticity_token" => token},
25
- "rack.session" => session
23
+ post 'features/search/boolean',
24
+ { 'action' => 'Enable', 'authenticity_token' => token },
25
+ 'rack.session' => session
26
26
  end
27
27
 
28
- it "enables the feature" do
28
+ it 'enables the feature' do
29
29
  expect(flipper.enabled?(:search)).to be(true)
30
30
  end
31
31
 
32
- it "redirects back to feature" do
32
+ it 'redirects back to feature' do
33
33
  expect(last_response.status).to be(302)
34
- expect(last_response.headers["Location"]).to eq("/features/search")
34
+ expect(last_response.headers['Location']).to eq('/features/search')
35
35
  end
36
36
  end
37
37
 
38
- context "with disable" do
38
+ context 'with disable' do
39
39
  before do
40
40
  flipper.enable :search
41
- post "features/search/boolean",
42
- {"action" => "Disable", "authenticity_token" => token},
43
- "rack.session" => session
41
+ post 'features/search/boolean',
42
+ { 'action' => 'Disable', 'authenticity_token' => token },
43
+ 'rack.session' => session
44
44
  end
45
45
 
46
- it "disables the feature" do
46
+ it 'disables the feature' do
47
47
  expect(flipper.enabled?(:search)).to be(false)
48
48
  end
49
49
 
50
- it "redirects back to feature" do
50
+ it 'redirects back to feature' do
51
51
  expect(last_response.status).to be(302)
52
- expect(last_response.headers["Location"]).to eq("/features/search")
52
+ expect(last_response.headers['Location']).to eq('/features/search')
53
53
  end
54
54
  end
55
55
  end