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
@@ -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