flipper-ui 1.2.1 → 1.4.0

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/examples/ui/basic.ru +4 -0
  3. data/flipper-ui.gemspec +3 -2
  4. data/lib/flipper/ui/action.rb +30 -46
  5. data/lib/flipper/ui/actions/actors_gate.rb +2 -8
  6. data/lib/flipper/ui/actions/add_feature.rb +0 -9
  7. data/lib/flipper/ui/actions/boolean_gate.rb +1 -1
  8. data/lib/flipper/ui/actions/cloud_migrate.rb +26 -0
  9. data/lib/flipper/ui/actions/feature.rb +0 -7
  10. data/lib/flipper/ui/actions/features.rb +2 -9
  11. data/lib/flipper/ui/actions/groups_gate.rb +2 -7
  12. data/lib/flipper/ui/actions/percentage_of_actors_gate.rb +2 -2
  13. data/lib/flipper/ui/actions/percentage_of_time_gate.rb +2 -2
  14. data/lib/flipper/ui/actions/settings.rb +0 -3
  15. data/lib/flipper/ui/configuration.rb +18 -4
  16. data/lib/flipper/ui/middleware.rb +1 -0
  17. data/lib/flipper/ui/public/css/bootstrap.min.css +6 -0
  18. data/lib/flipper/ui/public/js/application.js +17 -33
  19. data/lib/flipper/ui/public/js/bootstrap.min.js +7 -0
  20. data/lib/flipper/ui/public/js/popper.min.js +6 -0
  21. data/lib/flipper/ui/sources.json +5 -0
  22. data/lib/flipper/ui/util.rb +10 -0
  23. data/lib/flipper/ui/views/add_actor.erb +8 -4
  24. data/lib/flipper/ui/views/add_feature.erb +3 -3
  25. data/lib/flipper/ui/views/add_group.erb +14 -9
  26. data/lib/flipper/ui/views/feature.erb +93 -80
  27. data/lib/flipper/ui/views/features.erb +29 -29
  28. data/lib/flipper/ui/views/layout.erb +28 -20
  29. data/lib/flipper/ui/views/settings.erb +31 -4
  30. data/lib/flipper/ui.rb +16 -2
  31. data/lib/flipper/version.rb +1 -1
  32. data/spec/flipper/ui/actions/actors_gate_spec.rb +6 -6
  33. data/spec/flipper/ui/actions/add_feature_spec.rb +1 -1
  34. data/spec/flipper/ui/actions/boolean_gate_spec.rb +1 -1
  35. data/spec/flipper/ui/actions/cloud_migrate_spec.rb +54 -0
  36. data/spec/flipper/ui/actions/feature_spec.rb +28 -0
  37. data/spec/flipper/ui/actions/features_spec.rb +60 -3
  38. data/spec/flipper/ui/actions/groups_gate_spec.rb +6 -6
  39. data/spec/flipper/ui/actions/percentage_of_actors_gate_spec.rb +3 -3
  40. data/spec/flipper/ui/actions/percentage_of_time_gate_spec.rb +3 -3
  41. data/spec/flipper/ui/actions/settings_spec.rb +8 -0
  42. data/spec/flipper/ui/configuration_spec.rb +9 -4
  43. data/spec/flipper/ui_spec.rb +19 -31
  44. metadata +40 -35
  45. data/lib/flipper/ui/public/css/bootstrap-4.6.0.min.css +0 -7
  46. data/lib/flipper/ui/public/js/bootstrap-4.6.0.min.js +0 -7
  47. data/lib/flipper/ui/public/js/popper-1.12.9.min.js +0 -5
@@ -20,7 +20,7 @@ RSpec.describe Flipper::UI::Actions::ActorsGate do
20
20
  end
21
21
 
22
22
  it 'renders add new actor form' do
23
- form = '<form action="/features/search/actors" method="post" class="form-inline">'
23
+ form = '<form action="/features/search/actors" method="post" class="row">'
24
24
  expect(last_response.body).to include(form)
25
25
  end
26
26
  end
@@ -35,7 +35,7 @@ RSpec.describe Flipper::UI::Actions::ActorsGate do
35
35
  end
36
36
 
37
37
  it 'renders add new actor form' do
38
- form = '<form action="/features/a/b/actors" method="post" class="form-inline">'
38
+ form = '<form action="/features/a%2Fb/actors" method="post" class="row">'
39
39
  expect(last_response.body).to include(form)
40
40
  end
41
41
  end
@@ -73,7 +73,7 @@ RSpec.describe Flipper::UI::Actions::ActorsGate do
73
73
 
74
74
  context "when feature name contains space" do
75
75
  before do
76
- post 'features/sp%20ace/actors',
76
+ post 'features/sp+ace/actors',
77
77
  { 'value' => value, 'operation' => 'enable', 'authenticity_token' => token },
78
78
  'rack.session' => session
79
79
  end
@@ -84,7 +84,7 @@ RSpec.describe Flipper::UI::Actions::ActorsGate do
84
84
 
85
85
  it "redirects back to feature" do
86
86
  expect(last_response.status).to be(302)
87
- expect(last_response.headers['location']).to eq('/features/sp%20ace')
87
+ expect(last_response.headers['location']).to eq('/features/sp+ace')
88
88
  end
89
89
  end
90
90
 
@@ -114,7 +114,7 @@ RSpec.describe Flipper::UI::Actions::ActorsGate do
114
114
 
115
115
  it 'redirects back to feature' do
116
116
  expect(last_response.status).to be(302)
117
- expect(last_response.headers['location']).to eq('/features/search/actors?error=%22%22%20is%20not%20a%20valid%20actor%20value.')
117
+ expect(last_response.headers['location']).to eq('/features/search/actors?error=%22%22+is+not+a+valid+actor+value.')
118
118
  end
119
119
  end
120
120
 
@@ -123,7 +123,7 @@ RSpec.describe Flipper::UI::Actions::ActorsGate do
123
123
 
124
124
  it 'redirects back to feature' do
125
125
  expect(last_response.status).to be(302)
126
- expect(last_response.headers['location']).to eq('/features/search/actors?error=%22%22%20is%20not%20a%20valid%20actor%20value.')
126
+ expect(last_response.headers['location']).to eq('/features/search/actors?error=%22%22+is+not+a+valid+actor+value.')
127
127
  end
128
128
  end
129
129
  end
@@ -15,7 +15,7 @@ RSpec.describe Flipper::UI::Actions::AddFeature do
15
15
  end
16
16
 
17
17
  it 'renders template' do
18
- form = '<form action="/features" method="post" class="form-inline mb-2">'
18
+ form = '<form action="/features" method="post" class="row g-3 mb-2">'
19
19
  expect(last_response.body).to include(form)
20
20
  end
21
21
  end
@@ -43,7 +43,7 @@ RSpec.describe Flipper::UI::Actions::BooleanGate do
43
43
 
44
44
  it 'redirects back to feature' do
45
45
  expect(last_response.status).to be(302)
46
- expect(last_response.headers['location']).to eq('/features/sp%20ace')
46
+ expect(last_response.headers['location']).to eq('/features/sp+ace')
47
47
  end
48
48
  end
49
49
 
@@ -0,0 +1,54 @@
1
+ require 'flipper/cloud/migrate'
2
+
3
+ RSpec.describe Flipper::UI::Actions::CloudMigrate do
4
+ let(:token) do
5
+ if Rack::Protection::AuthenticityToken.respond_to?(:random_token)
6
+ Rack::Protection::AuthenticityToken.random_token
7
+ else
8
+ 'a'
9
+ end
10
+ end
11
+
12
+ let(:session) do
13
+ { :csrf => token, 'csrf' => token, '_csrf_token' => token }
14
+ end
15
+
16
+ describe "POST /settings/cloud" do
17
+ context "when migration succeeds" do
18
+ before do
19
+ flipper.enable :search
20
+ allow(Flipper::Cloud).to receive(:migrate).and_return(
21
+ Flipper::Cloud::MigrateResult.new(code: 200, url: "https://www.flippercloud.io/cloud/setup/abc123")
22
+ )
23
+
24
+ post '/settings/cloud',
25
+ {'authenticity_token' => token},
26
+ 'rack.session' => session
27
+ end
28
+
29
+ it 'redirects to the cloud URL' do
30
+ expect(last_response.status).to be(302)
31
+ expect(last_response.headers['location']).to eq('https://www.flippercloud.io/cloud/setup/abc123')
32
+ end
33
+ end
34
+
35
+ context "when migration fails" do
36
+ before do
37
+ flipper.enable :search
38
+ allow(Flipper::Cloud).to receive(:migrate).and_return(
39
+ Flipper::Cloud::MigrateResult.new(code: 500, url: nil)
40
+ )
41
+
42
+ post '/settings/cloud',
43
+ {'authenticity_token' => token},
44
+ 'rack.session' => session
45
+ end
46
+
47
+ it 'redirects back to settings with error' do
48
+ expect(last_response.status).to be(302)
49
+ expect(last_response.headers['location']).to include('/settings')
50
+ expect(last_response.headers['location']).to include('error=')
51
+ end
52
+ end
53
+ end
54
+ end
@@ -197,4 +197,32 @@ RSpec.describe Flipper::UI::Actions::Feature do
197
197
  expect(last_response.body).to include('a/b')
198
198
  end
199
199
  end
200
+
201
+ describe 'GET /features/:feature with dot dot slash repeated in feature name' do
202
+ before do
203
+ get '/features/..%2F..%2F..%2F..%2Fblah'
204
+ end
205
+
206
+ it 'responds with success' do
207
+ expect(last_response.status).to be(200)
208
+ end
209
+
210
+ it 'renders template' do
211
+ expect(last_response.body).to include('../../../../blah')
212
+ end
213
+ end
214
+
215
+ describe 'GET /features/:feature with question mark in feature name' do
216
+ before do
217
+ get '/features/can_do_stuff%3F'
218
+ end
219
+
220
+ it 'responds with success' do
221
+ expect(last_response.status).to be(200)
222
+ end
223
+
224
+ it 'renders template with question mark in feature name' do
225
+ expect(last_response.body).to include('can_do_stuff?')
226
+ end
227
+ end
200
228
  end
@@ -28,6 +28,18 @@ RSpec.describe Flipper::UI::Actions::Features do
28
28
  end
29
29
  end
30
30
 
31
+ it "escapes keys that are junky" do
32
+ flipper.add("../../../../blah")
33
+ flipper.add("this that")
34
+ flipper.add("foo/bar")
35
+ flipper.add("can_do_stuff?")
36
+ get '/features'
37
+ expect(last_response.body).to include("..%2F..%2F..%2F..%2Fblah")
38
+ expect(last_response.body).to include("this+that")
39
+ expect(last_response.body).to include("foo%2Fbar")
40
+ expect(last_response.body).to include("can_do_stuff%3F")
41
+ end
42
+
31
43
  context "when there are no features to list" do
32
44
  before do
33
45
  @original_fun_enabled = Flipper::UI.configuration.fun
@@ -78,6 +90,25 @@ RSpec.describe Flipper::UI::Actions::Features do
78
90
  expect(last_response.body).not_to include('<a class="btn btn-primary btn-sm" href="/features/new">Add Feature</a>')
79
91
  end
80
92
  end
93
+
94
+ context 'when descriptions have links' do
95
+ before do
96
+ Flipper::UI.configuration.show_feature_description_in_list = true
97
+ Flipper::UI.configuration.descriptions_source = lambda { |_keys|
98
+ { 'test_feature' => 'Check <a href="https://example.com">this link</a> for more info' }
99
+ }
100
+
101
+ flipper[:test_feature].enable
102
+ end
103
+
104
+ it 'strips anchor tags from descriptions to avoid nested links' do
105
+ get '/features'
106
+
107
+ expect(last_response.status).to eq(200)
108
+ expect(last_response.body).to include('Check this link for more info')
109
+ expect(last_response.body).not_to include('<a href="https://example.com">this link</a>')
110
+ end
111
+ end
81
112
  end
82
113
 
83
114
  describe 'POST /features' do
@@ -124,7 +155,33 @@ RSpec.describe Flipper::UI::Actions::Features do
124
155
 
125
156
  it 'redirects to feature' do
126
157
  expect(last_response.status).to be(302)
127
- expect(last_response.headers['location']).to eq('/features/notifications%20next')
158
+ expect(last_response.headers['location']).to eq('/features/notifications+next')
159
+ end
160
+ end
161
+
162
+ context 'feature name contains ../' do
163
+ let(:feature_name) { '../../../foo' }
164
+
165
+ it 'adds feature with space' do
166
+ expect(flipper.features.map(&:key)).to include(feature_name)
167
+ end
168
+
169
+ it 'redirects to feature' do
170
+ expect(last_response.status).to be(302)
171
+ expect(last_response.headers['location']).to eq('/features/..%2F..%2F..%2Ffoo')
172
+ end
173
+ end
174
+
175
+ context 'feature name contains question mark' do
176
+ let(:feature_name) { 'can_do_stuff?' }
177
+
178
+ it 'adds feature with question mark' do
179
+ expect(flipper.features.map(&:key)).to include('can_do_stuff?')
180
+ end
181
+
182
+ it 'redirects to feature with encoded question mark' do
183
+ expect(last_response.status).to be(302)
184
+ expect(last_response.headers['location']).to eq('/features/can_do_stuff%3F')
128
185
  end
129
186
  end
130
187
 
@@ -138,7 +195,7 @@ RSpec.describe Flipper::UI::Actions::Features do
138
195
 
139
196
  it 'redirects back to feature' do
140
197
  expect(last_response.status).to be(302)
141
- expect(last_response.headers['location']).to eq('/features/new?error=%22%22%20is%20not%20a%20valid%20feature%20name.')
198
+ expect(last_response.headers['location']).to eq('/features/new?error=%22%22+is+not+a+valid+feature+name.')
142
199
  end
143
200
  end
144
201
 
@@ -151,7 +208,7 @@ RSpec.describe Flipper::UI::Actions::Features do
151
208
 
152
209
  it 'redirects back to feature' do
153
210
  expect(last_response.status).to be(302)
154
- expect(last_response.headers['location']).to eq('/features/new?error=%22%22%20is%20not%20a%20valid%20feature%20name.')
211
+ expect(last_response.headers['location']).to eq('/features/new?error=%22%22+is+not+a+valid+feature+name.')
155
212
  end
156
213
  end
157
214
  end
@@ -26,7 +26,7 @@ RSpec.describe Flipper::UI::Actions::GroupsGate do
26
26
  end
27
27
 
28
28
  it 'renders add new group form' do
29
- form = '<form action="/features/search/groups" method="post" class="form-inline">'
29
+ form = '<form action="/features/search/groups" method="post" class="row">'
30
30
  expect(last_response.body).to include(form)
31
31
  end
32
32
  end
@@ -60,7 +60,7 @@ RSpec.describe Flipper::UI::Actions::GroupsGate do
60
60
 
61
61
  context 'feature name contains space' do
62
62
  before do
63
- post 'features/sp%20ace/groups',
63
+ post 'features/sp+ace/groups',
64
64
  { 'value' => group_name, 'operation' => 'enable', 'authenticity_token' => token },
65
65
  'rack.session' => session
66
66
  end
@@ -71,7 +71,7 @@ RSpec.describe Flipper::UI::Actions::GroupsGate do
71
71
 
72
72
  it 'redirects back to feature' do
73
73
  expect(last_response.status).to be(302)
74
- expect(last_response.headers['location']).to eq('/features/sp%20ace')
74
+ expect(last_response.headers['location']).to eq('/features/sp+ace')
75
75
  end
76
76
  end
77
77
 
@@ -89,7 +89,7 @@ RSpec.describe Flipper::UI::Actions::GroupsGate do
89
89
 
90
90
  it 'redirects back to feature' do
91
91
  expect(last_response.status).to be(302)
92
- expect(last_response.headers['location']).to eq('/features/search/groups?error=The%20group%20named%20%22not_here%22%20has%20not%20been%20registered.')
92
+ expect(last_response.headers['location']).to eq('/features/search/groups?error=The+group+named+%22not_here%22+has+not+been+registered.')
93
93
  end
94
94
  end
95
95
 
@@ -98,7 +98,7 @@ RSpec.describe Flipper::UI::Actions::GroupsGate do
98
98
 
99
99
  it 'redirects back to feature' do
100
100
  expect(last_response.status).to be(302)
101
- expect(last_response.headers['location']).to eq('/features/search/groups?error=The%20group%20named%20%22%22%20has%20not%20been%20registered.')
101
+ expect(last_response.headers['location']).to eq('/features/search/groups?error=The+group+named+%22%22+has+not+been+registered.')
102
102
  end
103
103
  end
104
104
 
@@ -107,7 +107,7 @@ RSpec.describe Flipper::UI::Actions::GroupsGate do
107
107
 
108
108
  it 'redirects back to feature' do
109
109
  expect(last_response.status).to be(302)
110
- expect(last_response.headers['location']).to eq('/features/search/groups?error=The%20group%20named%20%22%22%20has%20not%20been%20registered.')
110
+ expect(last_response.headers['location']).to eq('/features/search/groups?error=The+group+named+%22%22+has+not+been+registered.')
111
111
  end
112
112
  end
113
113
  end
@@ -30,7 +30,7 @@ RSpec.describe Flipper::UI::Actions::PercentageOfActorsGate do
30
30
 
31
31
  context 'with space in feature name' do
32
32
  before do
33
- post 'features/sp%20ace/percentage_of_actors',
33
+ post 'features/sp+ace/percentage_of_actors',
34
34
  { 'value' => '24', 'authenticity_token' => token },
35
35
  'rack.session' => session
36
36
  end
@@ -41,7 +41,7 @@ RSpec.describe Flipper::UI::Actions::PercentageOfActorsGate do
41
41
 
42
42
  it 'redirects back to feature' do
43
43
  expect(last_response.status).to be(302)
44
- expect(last_response.headers['location']).to eq('/features/sp%20ace')
44
+ expect(last_response.headers['location']).to eq('/features/sp+ace')
45
45
  end
46
46
  end
47
47
 
@@ -58,7 +58,7 @@ RSpec.describe Flipper::UI::Actions::PercentageOfActorsGate do
58
58
 
59
59
  it 'redirects back to feature' do
60
60
  expect(last_response.status).to be(302)
61
- expect(last_response.headers['location']).to eq('/features/search?error=Invalid%20percentage%20of%20actors%20value:%20value%20must%20be%20a%20positive%20number%20less%20than%20or%20equal%20to%20100,%20but%20was%20555')
61
+ 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')
62
62
  end
63
63
  end
64
64
  end
@@ -30,7 +30,7 @@ RSpec.describe Flipper::UI::Actions::PercentageOfTimeGate do
30
30
 
31
31
  context 'with space in feature name' do
32
32
  before do
33
- post 'features/sp%20ace/percentage_of_time',
33
+ post 'features/sp+ace/percentage_of_time',
34
34
  { 'value' => '24', 'authenticity_token' => token },
35
35
  'rack.session' => session
36
36
  end
@@ -41,7 +41,7 @@ RSpec.describe Flipper::UI::Actions::PercentageOfTimeGate do
41
41
 
42
42
  it 'redirects back to feature' do
43
43
  expect(last_response.status).to be(302)
44
- expect(last_response.headers['location']).to eq('/features/sp%20ace')
44
+ expect(last_response.headers['location']).to eq('/features/sp+ace')
45
45
  end
46
46
  end
47
47
 
@@ -58,7 +58,7 @@ RSpec.describe Flipper::UI::Actions::PercentageOfTimeGate do
58
58
 
59
59
  it 'redirects back to feature' do
60
60
  expect(last_response.status).to be(302)
61
- expect(last_response.headers['location']).to eq('/features/search?error=Invalid%20percentage%20of%20time%20value:%20value%20must%20be%20a%20positive%20number%20less%20than%20or%20equal%20to%20100,%20but%20was%20555')
61
+ 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')
62
62
  end
63
63
  end
64
64
  end
@@ -23,5 +23,13 @@ RSpec.describe Flipper::UI::Actions::Settings do
23
23
  it 'renders template' do
24
24
  expect(last_response.body).to include('Download')
25
25
  end
26
+
27
+ it 'includes migrate to Flipper Cloud card' do
28
+ expect(last_response.body).to include('Migrate to Flipper Cloud')
29
+ end
30
+
31
+ it 'shows feature count' do
32
+ expect(last_response.body).to include('features ready to migrate')
33
+ end
26
34
  end
27
35
  end
@@ -35,14 +35,19 @@ RSpec.describe Flipper::UI::Configuration do
35
35
  end
36
36
  end
37
37
 
38
- describe "#application_breadcrumb_href" do
38
+ describe "#application_href" do
39
39
  it "has default value" do
40
- expect(configuration.application_breadcrumb_href).to eq(nil)
40
+ expect(configuration.application_href).to eq(nil)
41
41
  end
42
42
 
43
43
  it "can be updated" do
44
- configuration.application_breadcrumb_href = 'http://www.myapp.com'
45
- expect(configuration.application_breadcrumb_href).to eq('http://www.myapp.com')
44
+ configuration.application_href = 'http://www.myapp.com'
45
+ expect(configuration.application_href).to eq('http://www.myapp.com')
46
+ end
47
+
48
+ it 'aliases application_breadcrumb_href to application_href' do
49
+ configuration.application_breadcrumb_href = "/myapp"
50
+ expect(configuration.application_href).to eq("/myapp")
46
51
  end
47
52
  end
48
53
 
@@ -76,56 +76,44 @@ RSpec.describe Flipper::UI do
76
76
  end
77
77
  end
78
78
 
79
- describe "application_breadcrumb_href" do
80
- it 'does not have an application_breadcrumb_href by default' do
81
- expect(configuration.application_breadcrumb_href).to be(nil)
79
+ describe "application_href" do
80
+ around do |example|
81
+ original_href = configuration.application_href
82
+ example.run
83
+ ensure
84
+ configuration.application_href = original_href
82
85
  end
83
86
 
84
- context 'with application_breadcrumb_href not set' do
85
- before do
86
- @original_application_breadcrumb_href = configuration.application_breadcrumb_href
87
- configuration.application_breadcrumb_href = nil
88
- end
89
-
90
- after do
91
- configuration.application_breadcrumb_href = @original_application_breadcrumb_href
92
- end
87
+ it 'does not have an application_href by default' do
88
+ expect(configuration.application_href).to be(nil)
89
+ end
93
90
 
94
- it 'does not add App breadcrumb' do
91
+ context 'with application_href not set' do
92
+ it 'does not add App link' do
95
93
  get '/features'
96
94
  expect(last_response.body).not_to include('<a href="/myapp">App</a>')
97
95
  end
98
96
  end
99
97
 
100
- context 'with application_breadcrumb_href set' do
98
+ context 'with application_href set' do
101
99
  before do
102
- @original_application_breadcrumb_href = configuration.application_breadcrumb_href
103
- configuration.application_breadcrumb_href = '/myapp'
100
+ configuration.application_href = '/myapp'
104
101
  end
105
102
 
106
- after do
107
- configuration.application_breadcrumb_href = @original_application_breadcrumb_href
108
- end
109
-
110
- it 'does add App breadcrumb' do
103
+ it 'does add App link' do
111
104
  get '/features'
112
- expect(last_response.body).to include('<a href="/myapp">App</a>')
105
+ expect(last_response.body).to match('<a.*href="/myapp"')
113
106
  end
114
107
  end
115
108
 
116
- context 'with application_breadcrumb_href set to full url' do
109
+ context 'with application_href set to full url' do
117
110
  before do
118
- @original_application_breadcrumb_href = configuration.application_breadcrumb_href
119
- configuration.application_breadcrumb_href = 'https://myapp.com/'
120
- end
121
-
122
- after do
123
- configuration.application_breadcrumb_href = @original_application_breadcrumb_href
111
+ configuration.application_href = "https://myapp.com/"
124
112
  end
125
113
 
126
- it 'does add App breadcrumb' do
114
+ it 'does add App link' do
127
115
  get '/features'
128
- expect(last_response.body).to include('<a href="https://myapp.com/">App</a>')
116
+ expect(last_response.body).to match('<a.*href="https://myapp.com/"')
129
117
  end
130
118
  end
131
119
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-15 00:00:00.000000000 Z
11
+ date: 2026-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -37,9 +37,9 @@ dependencies:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: 1.5.3
40
- - - "<="
40
+ - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: 4.0.0
42
+ version: 5.0.0
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -47,23 +47,43 @@ dependencies:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
49
  version: 1.5.3
50
- - - "<="
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: 5.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: rack-session
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 1.0.2
60
+ - - "<"
51
61
  - !ruby/object:Gem::Version
52
- version: 4.0.0
62
+ version: 3.0.0
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 1.0.2
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: 3.0.0
53
73
  - !ruby/object:Gem::Dependency
54
74
  name: flipper
55
75
  requirement: !ruby/object:Gem::Requirement
56
76
  requirements:
57
77
  - - "~>"
58
78
  - !ruby/object:Gem::Version
59
- version: 1.2.1
79
+ version: 1.4.0
60
80
  type: :runtime
61
81
  prerelease: false
62
82
  version_requirements: !ruby/object:Gem::Requirement
63
83
  requirements:
64
84
  - - "~>"
65
85
  - !ruby/object:Gem::Version
66
- version: 1.2.1
86
+ version: 1.4.0
67
87
  - !ruby/object:Gem::Dependency
68
88
  name: erubi
69
89
  requirement: !ruby/object:Gem::Requirement
@@ -90,14 +110,14 @@ dependencies:
90
110
  requirements:
91
111
  - - "<"
92
112
  - !ruby/object:Gem::Version
93
- version: '7'
113
+ version: '8'
94
114
  type: :runtime
95
115
  prerelease: false
96
116
  version_requirements: !ruby/object:Gem::Requirement
97
117
  requirements:
98
118
  - - "<"
99
119
  - !ruby/object:Gem::Version
100
- version: '7'
120
+ version: '8'
101
121
  description:
102
122
  email: support@flippercloud.io
103
123
  executables: []
@@ -116,6 +136,7 @@ files:
116
136
  - lib/flipper/ui/actions/actors_gate.rb
117
137
  - lib/flipper/ui/actions/add_feature.rb
118
138
  - lib/flipper/ui/actions/boolean_gate.rb
139
+ - lib/flipper/ui/actions/cloud_migrate.rb
119
140
  - lib/flipper/ui/actions/export.rb
120
141
  - lib/flipper/ui/actions/feature.rb
121
142
  - lib/flipper/ui/actions/features.rb
@@ -133,13 +154,14 @@ files:
133
154
  - lib/flipper/ui/error.rb
134
155
  - lib/flipper/ui/middleware.rb
135
156
  - lib/flipper/ui/public/css/application.css
136
- - lib/flipper/ui/public/css/bootstrap-4.6.0.min.css
157
+ - lib/flipper/ui/public/css/bootstrap.min.css
137
158
  - lib/flipper/ui/public/images/logo.png
138
159
  - lib/flipper/ui/public/js/application.js
139
- - lib/flipper/ui/public/js/bootstrap-4.6.0.min.js
160
+ - lib/flipper/ui/public/js/bootstrap.min.js
140
161
  - lib/flipper/ui/public/js/jquery-3.6.0.slim.js
141
- - lib/flipper/ui/public/js/popper-1.12.9.min.js
162
+ - lib/flipper/ui/public/js/popper.min.js
142
163
  - lib/flipper/ui/public/js/version.js
164
+ - lib/flipper/ui/sources.json
143
165
  - lib/flipper/ui/util.rb
144
166
  - lib/flipper/ui/views/add_actor.erb
145
167
  - lib/flipper/ui/views/add_feature.erb
@@ -156,6 +178,7 @@ files:
156
178
  - spec/flipper/ui/actions/actors_gate_spec.rb
157
179
  - spec/flipper/ui/actions/add_feature_spec.rb
158
180
  - spec/flipper/ui/actions/boolean_gate_spec.rb
181
+ - spec/flipper/ui/actions/cloud_migrate_spec.rb
159
182
  - spec/flipper/ui/actions/export_spec.rb
160
183
  - spec/flipper/ui/actions/feature_spec.rb
161
184
  - spec/flipper/ui/actions/features_spec.rb
@@ -179,7 +202,8 @@ metadata:
179
202
  homepage_uri: https://www.flippercloud.io
180
203
  source_code_uri: https://github.com/flippercloud/flipper
181
204
  bug_tracker_uri: https://github.com/flippercloud/flipper/issues
182
- changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.2.1
205
+ changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.4.0
206
+ funding_uri: https://github.com/sponsors/flippercloud
183
207
  post_install_message:
184
208
  rdoc_options: []
185
209
  require_paths:
@@ -195,27 +219,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
219
  - !ruby/object:Gem::Version
196
220
  version: '0'
197
221
  requirements: []
198
- rubygems_version: 3.5.3
222
+ rubygems_version: 3.5.22
199
223
  signing_key:
200
224
  specification_version: 4
201
225
  summary: Feature flag UI for the Flipper gem
202
- test_files:
203
- - spec/flipper/ui/action_spec.rb
204
- - spec/flipper/ui/actions/actors_gate_spec.rb
205
- - spec/flipper/ui/actions/add_feature_spec.rb
206
- - spec/flipper/ui/actions/boolean_gate_spec.rb
207
- - spec/flipper/ui/actions/export_spec.rb
208
- - spec/flipper/ui/actions/feature_spec.rb
209
- - spec/flipper/ui/actions/features_spec.rb
210
- - spec/flipper/ui/actions/file_spec.rb
211
- - spec/flipper/ui/actions/groups_gate_spec.rb
212
- - spec/flipper/ui/actions/home_spec.rb
213
- - spec/flipper/ui/actions/import_spec.rb
214
- - spec/flipper/ui/actions/percentage_of_actors_gate_spec.rb
215
- - spec/flipper/ui/actions/percentage_of_time_gate_spec.rb
216
- - spec/flipper/ui/actions/settings_spec.rb
217
- - spec/flipper/ui/configuration_spec.rb
218
- - spec/flipper/ui/decorators/feature_spec.rb
219
- - spec/flipper/ui/decorators/gate_spec.rb
220
- - spec/flipper/ui/util_spec.rb
221
- - spec/flipper/ui_spec.rb
226
+ test_files: []