flipper-ui 0.10.2 → 0.11.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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