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
@@ -1,16 +1,16 @@
1
1
  require 'helper'
2
2
 
3
3
  RSpec.describe Flipper::UI::Actions::Home do
4
- describe "GET /" do
4
+ describe 'GET /' do
5
5
  before do
6
6
  flipper[:stats].enable
7
7
  flipper[:search].enable
8
- get "/"
8
+ get '/'
9
9
  end
10
10
 
11
- it "responds with redirect" do
11
+ it 'responds with redirect' do
12
12
  expect(last_response.status).to be(302)
13
- expect(last_response.headers["Location"]).to eq("/features")
13
+ expect(last_response.headers['Location']).to eq('/features')
14
14
  end
15
15
  end
16
16
  end
@@ -1,54 +1,56 @@
1
1
  require 'helper'
2
2
 
3
3
  RSpec.describe Flipper::UI::Actions::PercentageOfActorsGate 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/percentage_of_actors" do
20
- context "with valid value" do
19
+ describe 'POST /features/:feature/percentage_of_actors' do
20
+ context 'with valid value' do
21
21
  before do
22
- post "features/search/percentage_of_actors",
23
- {"value" => "24", "authenticity_token" => token},
24
- "rack.session" => session
22
+ post 'features/search/percentage_of_actors',
23
+ { 'value' => '24', 'authenticity_token' => token },
24
+ 'rack.session' => session
25
25
  end
26
26
 
27
- it "enables the feature" do
27
+ it 'enables the feature' do
28
28
  expect(flipper[:search].percentage_of_actors_value).to be(24)
29
29
  end
30
30
 
31
- it "redirects back to feature" do
31
+ it 'redirects back to feature' do
32
32
  expect(last_response.status).to be(302)
33
- expect(last_response.headers["Location"]).to eq("/features/search")
33
+ expect(last_response.headers['Location']).to eq('/features/search')
34
34
  end
35
35
  end
36
36
 
37
- context "with invalid value" do
37
+ context 'with invalid value' do
38
38
  before do
39
- post "features/search/percentage_of_actors",
40
- {"value" => "555", "authenticity_token" => token},
41
- "rack.session" => session
39
+ post 'features/search/percentage_of_actors',
40
+ { 'value' => '555', 'authenticity_token' => token },
41
+ 'rack.session' => session
42
42
  end
43
43
 
44
- it "does not change value" do
44
+ it 'does not change value' do
45
45
  expect(flipper[:search].percentage_of_actors_value).to be(0)
46
46
  end
47
47
 
48
- it "redirects back to feature" do
48
+ # rubocop:disable Metrics/LineLength
49
+ it 'redirects back to feature' do
49
50
  expect(last_response.status).to be(302)
50
- expect(last_response.headers["Location"]).to eq("/features/search?error=Invalid+percentage+of+actors+value%3A+value+must+be+a+positive+number+less+than+or+equal+to+100%2C+but+was+555")
51
+ expect(last_response.headers['Location']).to eq('/features/search?error=Invalid+percentage+of+actors+value%3A+value+must+be+a+positive+number+less+than+or+equal+to+100%2C+but+was+555')
51
52
  end
53
+ # rubocop:enable Metrics/LineLength
52
54
  end
53
55
  end
54
56
  end
@@ -1,54 +1,56 @@
1
1
  require 'helper'
2
2
 
3
3
  RSpec.describe Flipper::UI::Actions::PercentageOfTimeGate 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/percentage_of_time" do
20
- context "with valid value" do
19
+ describe 'POST /features/:feature/percentage_of_time' do
20
+ context 'with valid value' do
21
21
  before do
22
- post "features/search/percentage_of_time",
23
- {"value" => "24", "authenticity_token" => token},
24
- "rack.session" => session
22
+ post 'features/search/percentage_of_time',
23
+ { 'value' => '24', 'authenticity_token' => token },
24
+ 'rack.session' => session
25
25
  end
26
26
 
27
- it "enables the feature" do
27
+ it 'enables the feature' do
28
28
  expect(flipper[:search].percentage_of_time_value).to be(24)
29
29
  end
30
30
 
31
- it "redirects back to feature" do
31
+ it 'redirects back to feature' do
32
32
  expect(last_response.status).to be(302)
33
- expect(last_response.headers["Location"]).to eq("/features/search")
33
+ expect(last_response.headers['Location']).to eq('/features/search')
34
34
  end
35
35
  end
36
36
 
37
- context "with invalid value" do
37
+ context 'with invalid value' do
38
38
  before do
39
- post "features/search/percentage_of_time",
40
- {"value" => "555", "authenticity_token" => token},
41
- "rack.session" => session
39
+ post 'features/search/percentage_of_time',
40
+ { 'value' => '555', 'authenticity_token' => token },
41
+ 'rack.session' => session
42
42
  end
43
43
 
44
- it "does not change value" do
44
+ it 'does not change value' do
45
45
  expect(flipper[:search].percentage_of_time_value).to be(0)
46
46
  end
47
47
 
48
- it "redirects back to feature" do
48
+ # rubocop:disable Metrics/LineLength
49
+ it 'redirects back to feature' do
49
50
  expect(last_response.status).to be(302)
50
- expect(last_response.headers["Location"]).to eq("/features/search?error=Invalid+percentage+of+time+value%3A+value+must+be+a+positive+number+less+than+or+equal+to+100%2C+but+was+555")
51
+ expect(last_response.headers['Location']).to eq('/features/search?error=Invalid+percentage+of+time+value%3A+value+must+be+a+positive+number+less+than+or+equal+to+100%2C+but+was+555')
51
52
  end
53
+ # rubocop:enable Metrics/LineLength
52
54
  end
53
55
  end
54
56
  end
@@ -7,85 +7,85 @@ RSpec.describe Flipper::UI::Decorators::Feature do
7
7
  let(:flipper) { build_flipper }
8
8
  let(:feature) { flipper[:some_awesome_feature] }
9
9
 
10
- subject {
10
+ subject do
11
11
  described_class.new(feature)
12
- }
12
+ end
13
13
 
14
- describe "#initialize" do
15
- it "sets the feature" do
14
+ describe '#initialize' do
15
+ it 'sets the feature' do
16
16
  expect(subject.feature).to be(feature)
17
17
  end
18
18
  end
19
19
 
20
- describe "#pretty_name" do
21
- it "capitalizes each word separated by underscores" do
20
+ describe '#pretty_name' do
21
+ it 'capitalizes each word separated by underscores' do
22
22
  expect(subject.pretty_name).to eq('Some Awesome Feature')
23
23
  end
24
24
  end
25
25
 
26
- describe "#as_json" do
26
+ describe '#as_json' do
27
27
  before do
28
28
  @result = subject.as_json
29
29
  end
30
30
 
31
- it "returns Hash" do
31
+ it 'returns Hash' do
32
32
  expect(@result).to be_instance_of(Hash)
33
33
  end
34
34
 
35
- it "includes id" do
35
+ it 'includes id' do
36
36
  expect(@result['id']).to eq('some_awesome_feature')
37
37
  end
38
38
 
39
- it "includes pretty name" do
39
+ it 'includes pretty name' do
40
40
  expect(@result['name']).to eq('Some Awesome Feature')
41
41
  end
42
42
 
43
- it "includes state" do
43
+ it 'includes state' do
44
44
  expect(@result['state']).to eq('off')
45
45
  end
46
46
 
47
- it "includes gates" do
48
- gates = subject.gates.map { |gate|
47
+ it 'includes gates' do
48
+ gates = subject.gates.map do |gate|
49
49
  value = subject.gate_values[gate.key]
50
50
  Flipper::UI::Decorators::Gate.new(gate, value).as_json
51
- }
51
+ end
52
52
  expect(@result['gates']).to eq(gates)
53
53
  end
54
54
  end
55
55
 
56
- describe "#<=>" do
57
- let(:on) {
56
+ describe '#<=>' do
57
+ let(:on) do
58
58
  flipper.enable(:on_a)
59
59
  described_class.new(flipper[:on_a])
60
- }
60
+ end
61
61
 
62
- let(:on_b) {
62
+ let(:on_b) do
63
63
  flipper.enable(:on_b)
64
64
  described_class.new(flipper[:on_b])
65
- }
65
+ end
66
66
 
67
- let(:conditional) {
67
+ let(:conditional) do
68
68
  flipper.enable_percentage_of_time :conditional_a, 5
69
69
  described_class.new(flipper[:conditional_a])
70
- }
70
+ end
71
71
 
72
- let(:off) {
72
+ let(:off) do
73
73
  described_class.new(flipper[:off_a])
74
- }
74
+ end
75
75
 
76
- it "sorts :on before :conditional" do
76
+ it 'sorts :on before :conditional' do
77
77
  expect((on <=> conditional)).to be(-1)
78
78
  end
79
79
 
80
- it "sorts :on before :off" do
80
+ it 'sorts :on before :off' do
81
81
  expect((on <=> conditional)).to be(-1)
82
82
  end
83
83
 
84
- it "sorts :conditional before :off" do
84
+ it 'sorts :conditional before :off' do
85
85
  expect((on <=> conditional)).to be(-1)
86
86
  end
87
87
 
88
- it "sorts on key for identical states" do
88
+ it 'sorts on key for identical states' do
89
89
  expect((on <=> on_b)).to be(-1)
90
90
  end
91
91
  end
@@ -9,38 +9,38 @@ RSpec.describe Flipper::UI::Decorators::Gate do
9
9
  let(:feature) { flipper[:some_awesome_feature] }
10
10
  let(:gate) { feature.gate(:boolean) }
11
11
 
12
- subject {
12
+ subject do
13
13
  described_class.new(gate, false)
14
- }
14
+ end
15
15
 
16
- describe "#initialize" do
17
- it "sets gate" do
16
+ describe '#initialize' do
17
+ it 'sets gate' do
18
18
  expect(subject.gate).to be(gate)
19
19
  end
20
20
 
21
- it "sets value" do
21
+ it 'sets value' do
22
22
  expect(subject.value).to eq(false)
23
23
  end
24
24
  end
25
25
 
26
- describe "#as_json" do
26
+ describe '#as_json' do
27
27
  before do
28
28
  @result = subject.as_json
29
29
  end
30
30
 
31
- it "returns Hash" do
31
+ it 'returns Hash' do
32
32
  expect(@result).to be_instance_of(Hash)
33
33
  end
34
34
 
35
- it "includes key" do
35
+ it 'includes key' do
36
36
  expect(@result['key']).to eq('boolean')
37
37
  end
38
38
 
39
- it "includes pretty name" do
39
+ it 'includes pretty name' do
40
40
  expect(@result['name']).to eq('boolean')
41
41
  end
42
42
 
43
- it "includes value" do
43
+ it 'includes value' do
44
44
  expect(@result['value']).to be(false)
45
45
  end
46
46
  end
@@ -2,15 +2,15 @@ require 'helper'
2
2
  require 'flipper/ui/util'
3
3
 
4
4
  RSpec.describe Flipper::UI::Util do
5
- describe "#blank?" do
6
- context "with a string" do
7
- it "returns true if blank" do
5
+ describe '#blank?' do
6
+ context 'with a string' do
7
+ it 'returns true if blank' do
8
8
  expect(described_class.blank?(nil)).to be(true)
9
9
  expect(described_class.blank?('')).to be(true)
10
10
  expect(described_class.blank?(' ')).to be(true)
11
11
  end
12
12
 
13
- it "returns false if not blank" do
13
+ it 'returns false if not blank' do
14
14
  expect(described_class.blank?('nope')).to be(false)
15
15
  end
16
16
  end
@@ -1,128 +1,128 @@
1
1
  require 'helper'
2
2
 
3
3
  RSpec.describe Flipper::UI 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 "Initializing middleware with flipper instance" do
19
+ describe 'Initializing middleware with flipper instance' do
20
20
  let(:app) { build_app(flipper) }
21
21
 
22
- it "works" do
22
+ it 'works' do
23
23
  flipper.enable :some_great_feature
24
- get "/features"
24
+ get '/features'
25
25
  expect(last_response.status).to be(200)
26
- expect(last_response.body).to include("some_great_feature")
26
+ expect(last_response.body).to include('some_great_feature')
27
27
  end
28
28
  end
29
29
 
30
- describe "Initializing middleware lazily with a block" do
31
- let(:app) {
32
- build_app(lambda { flipper })
33
- }
30
+ describe 'Initializing middleware lazily with a block' do
31
+ let(:app) do
32
+ build_app(-> { flipper })
33
+ end
34
34
 
35
- it "works" do
35
+ it 'works' do
36
36
  flipper.enable :some_great_feature
37
- get "/features"
37
+ get '/features'
38
38
  expect(last_response.status).to be(200)
39
- expect(last_response.body).to include("some_great_feature")
39
+ expect(last_response.body).to include('some_great_feature')
40
40
  end
41
41
  end
42
42
 
43
- describe "Request method unsupported by action" do
44
- it "raises error" do
45
- expect {
43
+ describe 'Request method unsupported by action' do
44
+ it 'raises error' do
45
+ expect do
46
46
  head '/features'
47
- }.to raise_error(Flipper::UI::RequestMethodNotSupported)
47
+ end.to raise_error(Flipper::UI::RequestMethodNotSupported)
48
48
  end
49
49
  end
50
50
 
51
- describe "Inspecting the built Rack app" do
52
- it "returns a String" do
51
+ describe 'Inspecting the built Rack app' do
52
+ it 'returns a String' do
53
53
  expect(build_app(flipper).inspect).to be_a(String)
54
54
  end
55
55
  end
56
56
 
57
57
  # See https://github.com/jnunemaker/flipper/issues/80
58
- it "can route features with names that match static directories" do
59
- post "features/refactor-images/actors",
60
- {"value" => "User:6", "operation" => "enable", "authenticity_token" => token},
61
- "rack.session" => session
58
+ it 'can route features with names that match static directories' do
59
+ post 'features/refactor-images/actors',
60
+ { 'value' => 'User:6', 'operation' => 'enable', 'authenticity_token' => token },
61
+ 'rack.session' => session
62
62
  expect(last_response.status).to be(302)
63
- expect(last_response.headers["Location"]).to eq("/features/refactor-images")
63
+ expect(last_response.headers['Location']).to eq('/features/refactor-images')
64
64
  end
65
65
 
66
- it "should not have an application_breadcrumb_href by default" do
67
- expect(Flipper::UI.application_breadcrumb_href).to be(nil)
66
+ it 'does not have an application_breadcrumb_href by default' do
67
+ expect(described_class.application_breadcrumb_href).to be(nil)
68
68
  end
69
69
 
70
- context "with application_breadcrumb_href not set" do
70
+ context 'with application_breadcrumb_href not set' do
71
71
  before do
72
- @original_application_breadcrumb_href = Flipper::UI.application_breadcrumb_href
73
- Flipper::UI.application_breadcrumb_href = nil
72
+ @original_application_breadcrumb_href = described_class.application_breadcrumb_href
73
+ described_class.application_breadcrumb_href = nil
74
74
  end
75
75
 
76
76
  after do
77
- Flipper::UI.application_breadcrumb_href = @original_application_breadcrumb_href
77
+ described_class.application_breadcrumb_href = @original_application_breadcrumb_href
78
78
  end
79
79
 
80
80
  it 'does not add App breadcrumb' do
81
- get "/features"
82
- expect(last_response.body).to_not include('<a href="/myapp">App</a>')
81
+ get '/features'
82
+ expect(last_response.body).not_to include('<a href="/myapp">App</a>')
83
83
  end
84
84
  end
85
85
 
86
- context "with application_breadcrumb_href set" do
86
+ context 'with application_breadcrumb_href set' do
87
87
  before do
88
- @original_application_breadcrumb_href = Flipper::UI.application_breadcrumb_href
89
- Flipper::UI.application_breadcrumb_href = "/myapp"
88
+ @original_application_breadcrumb_href = described_class.application_breadcrumb_href
89
+ described_class.application_breadcrumb_href = '/myapp'
90
90
  end
91
91
 
92
92
  after do
93
- Flipper::UI.application_breadcrumb_href = @original_application_breadcrumb_href
93
+ described_class.application_breadcrumb_href = @original_application_breadcrumb_href
94
94
  end
95
95
 
96
96
  it 'does add App breadcrumb' do
97
- get "/features"
97
+ get '/features'
98
98
  expect(last_response.body).to include('<a href="/myapp">App</a>')
99
99
  end
100
100
  end
101
101
 
102
- context "with application_breadcrumb_href set to full url" do
102
+ context 'with application_breadcrumb_href set to full url' do
103
103
  before do
104
- @original_application_breadcrumb_href = Flipper::UI.application_breadcrumb_href
105
- Flipper::UI.application_breadcrumb_href = "https://myapp.com/"
104
+ @original_application_breadcrumb_href = described_class.application_breadcrumb_href
105
+ described_class.application_breadcrumb_href = 'https://myapp.com/'
106
106
  end
107
107
 
108
108
  after do
109
- Flipper::UI.application_breadcrumb_href = @original_application_breadcrumb_href
109
+ described_class.application_breadcrumb_href = @original_application_breadcrumb_href
110
110
  end
111
111
 
112
112
  it 'does add App breadcrumb' do
113
- get "/features"
113
+ get '/features'
114
114
  expect(last_response.body).to include('<a href="https://myapp.com/">App</a>')
115
115
  end
116
116
  end
117
117
 
118
- it "should set feature_creation_enabled to true by default" do
119
- expect(Flipper::UI.feature_creation_enabled).to be(true)
118
+ it 'sets feature_creation_enabled to true by default' do
119
+ expect(described_class.feature_creation_enabled).to be(true)
120
120
  end
121
121
 
122
- context "with feature_creation_enabled set to true" do
122
+ context 'with feature_creation_enabled set to true' do
123
123
  before do
124
- @original_feature_creation_enabled = Flipper::UI.feature_creation_enabled
125
- Flipper::UI.feature_creation_enabled = true
124
+ @original_feature_creation_enabled = described_class.feature_creation_enabled
125
+ described_class.feature_creation_enabled = true
126
126
  end
127
127
 
128
128
  it 'has the add_feature button' do
@@ -131,24 +131,23 @@ RSpec.describe Flipper::UI do
131
131
  end
132
132
 
133
133
  after do
134
- Flipper::UI.feature_creation_enabled = @original_feature_creation_enabled
134
+ described_class.feature_creation_enabled = @original_feature_creation_enabled
135
135
  end
136
136
  end
137
137
 
138
- context "with feature_creation_enabled set to false" do
138
+ context 'with feature_creation_enabled set to false' do
139
139
  before do
140
- @original_feature_creation_enabled = Flipper::UI.feature_creation_enabled
141
- Flipper::UI.feature_creation_enabled = false
140
+ @original_feature_creation_enabled = described_class.feature_creation_enabled
141
+ described_class.feature_creation_enabled = false
142
142
  end
143
143
 
144
144
  it 'does not have the add_feature button' do
145
145
  get '/features'
146
- expect(last_response.body).to_not include('Add Feature')
146
+ expect(last_response.body).not_to include('Add Feature')
147
147
  end
148
148
 
149
149
  after do
150
- Flipper::UI.feature_creation_enabled = @original_feature_creation_enabled
150
+ described_class.feature_creation_enabled = @original_feature_creation_enabled
151
151
  end
152
152
  end
153
-
154
153
  end