flipper-ui 1.1.2 → 1.2.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.
- checksums.yaml +4 -4
- data/examples/ui/basic.ru +2 -2
- data/lib/flipper/ui/action.rb +4 -3
- data/lib/flipper/ui/configuration.rb +5 -0
- data/lib/flipper/ui/public/js/application.js +12 -1
- data/lib/flipper/ui/public/js/version.js +33 -0
- data/lib/flipper/ui/views/feature.erb +8 -3
- data/lib/flipper/ui/views/layout.erb +16 -1
- data/lib/flipper/ui.rb +1 -1
- data/lib/flipper/version.rb +11 -1
- data/spec/flipper/ui/actions/actors_gate_spec.rb +5 -5
- data/spec/flipper/ui/actions/boolean_gate_spec.rb +3 -3
- data/spec/flipper/ui/actions/export_spec.rb +2 -2
- data/spec/flipper/ui/actions/feature_spec.rb +26 -5
- data/spec/flipper/ui/actions/features_spec.rb +4 -4
- data/spec/flipper/ui/actions/groups_gate_spec.rb +6 -6
- data/spec/flipper/ui/actions/home_spec.rb +1 -1
- data/spec/flipper/ui/actions/import_spec.rb +1 -1
- data/spec/flipper/ui/actions/percentage_of_actors_gate_spec.rb +3 -3
- data/spec/flipper/ui/actions/percentage_of_time_gate_spec.rb +3 -3
- data/spec/flipper/ui_spec.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b33985781ada74b2666ef3b636288e1c5316b7f32f8178f3adafccf3f30e7c4f
|
4
|
+
data.tar.gz: 637de7cc0214932ea6fa47aa4d3a4d32e3b8e4dd9b4e97417a610a9405fc7898
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebc76af3eda0bf9b60912dc58b99fcaf65677a485cfa9ed4ca7a52bcf12934a6870680eb702869faa47f930575cc4b1046b3ddc34c2958f5cf7b4a504dbd7f48
|
7
|
+
data.tar.gz: a94f123f0e800036d602df242825c0452e081ccb91010f7642ecb118888b85e35c8eba63377f1fa3e1b05037ced0d2e9938413d554d0b52683709dafad11e2f7
|
data/examples/ui/basic.ru
CHANGED
@@ -42,8 +42,8 @@ Flipper::UI.configure do |config|
|
|
42
42
|
|
43
43
|
config.actor_names_source = lambda do |_keys|
|
44
44
|
{
|
45
|
-
'1' => 'John',
|
46
|
-
'6' => 'Brandon',
|
45
|
+
'1' => '<a href="https://johnnunemaker.com">John</a>',
|
46
|
+
'6' => '<a href="https://opensoul.org">Brandon</a>',
|
47
47
|
}
|
48
48
|
end
|
49
49
|
end
|
data/lib/flipper/ui/action.rb
CHANGED
@@ -53,6 +53,7 @@ module Flipper
|
|
53
53
|
style-src 'self' 'unsafe-inline';
|
54
54
|
style-src-attr 'unsafe-inline' ;
|
55
55
|
style-src-elem 'self';
|
56
|
+
connect-src https://www.flippercloud.io;
|
56
57
|
CSP
|
57
58
|
|
58
59
|
# Public: Call this in subclasses so the action knows its route.
|
@@ -108,7 +109,7 @@ module Flipper
|
|
108
109
|
@flipper = flipper
|
109
110
|
@request = request
|
110
111
|
@code = 200
|
111
|
-
@headers = {
|
112
|
+
@headers = {Rack::CONTENT_TYPE => 'text/plain'}
|
112
113
|
@breadcrumbs =
|
113
114
|
if Flipper::UI.configuration.application_breadcrumb_href
|
114
115
|
[Breadcrumb.new('App', Flipper::UI.configuration.application_breadcrumb_href)]
|
@@ -158,7 +159,7 @@ module Flipper
|
|
158
159
|
#
|
159
160
|
# Returns a response.
|
160
161
|
def view_response(name)
|
161
|
-
header
|
162
|
+
header Rack::CONTENT_TYPE, 'text/html'
|
162
163
|
header 'content-security-policy', CONTENT_SECURITY_POLICY
|
163
164
|
body = view_with_layout { view_without_layout name }
|
164
165
|
halt [@code, @headers, [body]]
|
@@ -171,7 +172,7 @@ module Flipper
|
|
171
172
|
#
|
172
173
|
# Returns a response.
|
173
174
|
def json_response(object)
|
174
|
-
header
|
175
|
+
header Rack::CONTENT_TYPE, 'application/json'
|
175
176
|
body = case object
|
176
177
|
when String
|
177
178
|
object
|
@@ -63,6 +63,10 @@ module Flipper
|
|
63
63
|
# Default is false.
|
64
64
|
attr_accessor :confirm_fully_enable
|
65
65
|
|
66
|
+
# Public: if you want to get a confirm pop up box while disabling a feature
|
67
|
+
# Default is false.
|
68
|
+
attr_accessor :confirm_disable
|
69
|
+
|
66
70
|
VALID_BANNER_CLASS_VALUES = %w(
|
67
71
|
danger
|
68
72
|
dark
|
@@ -91,6 +95,7 @@ module Flipper
|
|
91
95
|
@show_feature_description_in_list = false
|
92
96
|
@actors_separator = ','
|
93
97
|
@confirm_fully_enable = false
|
98
|
+
@confirm_disable = true
|
94
99
|
@read_only = false
|
95
100
|
end
|
96
101
|
|
@@ -14,7 +14,18 @@ $(function () {
|
|
14
14
|
e.preventDefault();
|
15
15
|
}
|
16
16
|
});
|
17
|
-
|
17
|
+
|
18
|
+
$("#disable_feature__button").on("click", function (e) {
|
19
|
+
const featureName = $(e.target).data("confirmation-text");
|
20
|
+
const promptMessage = prompt(
|
21
|
+
`Are you sure you want to disable this feature for everyone? Please enter the name of the feature to confirm it: ${featureName}`
|
22
|
+
);
|
23
|
+
|
24
|
+
if (promptMessage !== featureName) {
|
25
|
+
e.preventDefault();
|
26
|
+
}
|
27
|
+
});
|
28
|
+
|
18
29
|
$("#delete_feature__button").on("click", function (e) {
|
19
30
|
const featureName = $(e.target).data("confirmation-text");
|
20
31
|
const promptMessage = prompt(
|
@@ -0,0 +1,33 @@
|
|
1
|
+
// Get the latest release from RubyGems.org and show a badge if it's not the current version
|
2
|
+
function checkLatestRelease() {
|
3
|
+
// Skip check if last check was less than 1 day ago
|
4
|
+
if(localStorage.getItem('flipper.releaseCheckedAt') > new Date().getTime() - 86400000) return
|
5
|
+
|
6
|
+
// store the last time we checked for a new version
|
7
|
+
localStorage.setItem('flipper.releaseCheckedAt', new Date().getTime())
|
8
|
+
|
9
|
+
fetch('https://www.flippercloud.io/release.json').then(response => {
|
10
|
+
// Something went wrong, so just give up
|
11
|
+
if(!response.ok) return
|
12
|
+
|
13
|
+
response.json().then(release => {
|
14
|
+
localStorage.setItem('flipper.release', JSON.stringify(release))
|
15
|
+
showReleaseBadge()
|
16
|
+
})
|
17
|
+
})
|
18
|
+
}
|
19
|
+
|
20
|
+
// Show a badge if a new release is available
|
21
|
+
function showReleaseBadge() {
|
22
|
+
const badge = document.querySelector('#new-version-badge')
|
23
|
+
const release = JSON.parse(localStorage.getItem('flipper.release') || false)
|
24
|
+
|
25
|
+
if(!badge || !release || badge.dataset.version === release.version) return
|
26
|
+
|
27
|
+
badge.innerText = `${release.version} available!`
|
28
|
+
badge.setAttribute('href', release.changelog_uri)
|
29
|
+
badge.classList.remove('d-none')
|
30
|
+
}
|
31
|
+
|
32
|
+
checkLatestRelease()
|
33
|
+
showReleaseBadge()
|
@@ -66,7 +66,7 @@
|
|
66
66
|
<div class="col col-mr-auto pl-md-5">
|
67
67
|
<h6 class="m-0">
|
68
68
|
<% if Flipper::UI::Util.present?(@feature.actor_names[item]) %>
|
69
|
-
|
69
|
+
<%== Sanitize.fragment("#{@feature.actor_names[item]} (#{item})", Sanitize::Config::BASIC) %>
|
70
70
|
<% else %>
|
71
71
|
<%= item %>
|
72
72
|
<% end %>
|
@@ -263,8 +263,13 @@
|
|
263
263
|
|
264
264
|
<% unless @feature.off? %>
|
265
265
|
<div class="col">
|
266
|
-
<button type="submit" name="action" value="Disable" class="btn btn-outline-danger btn-block">
|
267
|
-
<span class="d-block" data-toggle="tooltip"
|
266
|
+
<button type="submit" name="action" value="Disable" <% if Flipper::UI.configuration.confirm_disable %>id="disable_feature__button"<% end %> class="btn btn-outline-danger btn-block">
|
267
|
+
<span class="d-block" data-toggle="tooltip"
|
268
|
+
<% if Flipper::UI.configuration.confirm_disable %>
|
269
|
+
data-confirmation-text="<%= feature_name %>"
|
270
|
+
<% end %>
|
271
|
+
title="Disable for everyone by clearing all percentages, groups and actors."
|
272
|
+
>
|
268
273
|
Disable
|
269
274
|
</span>
|
270
275
|
</button>
|
@@ -21,6 +21,20 @@
|
|
21
21
|
<a href="https://www.flippercloud.io/docs/ui?utm_source=oss&utm_medium=ui&utm_campaign=docs">Docs</a> •
|
22
22
|
<a href="<%= script_name %>/settings">Settings</a> •
|
23
23
|
Version: <%= Flipper::VERSION %>
|
24
|
+
<a href="#" class="badge badge-warning ml-2 d-none" style="font-size:100%" id="new-version-badge" data-version="<%= Flipper::VERSION %>">
|
25
|
+
</a>
|
26
|
+
|
27
|
+
<% if Flipper.deprecated_ruby_version? %>
|
28
|
+
<a href="https://github.com/flippercloud/flipper/pull/776" class="badge badge-danger ml-2" style="font-size:100%">
|
29
|
+
Ruby <%= RUBY_VERSION %> deprecated
|
30
|
+
</a>
|
31
|
+
<% end %>
|
32
|
+
|
33
|
+
<% if defined?(Rails) && Flipper::Engine.deprecated_rails_version? %>
|
34
|
+
<a href="https://github.com/flippercloud/flipper/pull/776" class="badge badge-danger ml-2" style="font-size:100%">
|
35
|
+
Rails <%= Rails.version %> deprecated
|
36
|
+
</a>
|
37
|
+
<% end %>
|
24
38
|
</div>
|
25
39
|
|
26
40
|
<nav aria-label="breadcrumb">
|
@@ -60,6 +74,7 @@
|
|
60
74
|
<script src="<%= script_name + jquery_js[:src] %>" integrity="<%= jquery_js[:hash] %>" crossorigin="anonymous"></script>
|
61
75
|
<script src="<%= script_name + popper_js[:src] %>" integrity="<%= popper_js[:hash] %>" crossorigin="anonymous"></script>
|
62
76
|
<script src="<%= script_name + bootstrap_js[:src] %>" integrity="<%= bootstrap_js[:hash] %>" crossorigin="anonymous"></script>
|
63
|
-
<script src="<%= script_name %>/js/application.js"></script>
|
77
|
+
<script src="<%= script_name %>/js/application.js?v=<%= Flipper::VERSION %>"></script>
|
78
|
+
<script src="<%= script_name %>/js/version.js?v=<%= Flipper::VERSION %>"></script>
|
64
79
|
</body>
|
65
80
|
</html>
|
data/lib/flipper/ui.rb
CHANGED
@@ -22,7 +22,7 @@ module Flipper
|
|
22
22
|
env_key = options.fetch(:env_key, 'flipper')
|
23
23
|
rack_protection_options = options.fetch(:rack_protection, use: :authenticity_token)
|
24
24
|
|
25
|
-
app = ->(_) { [200, {
|
25
|
+
app = ->(_) { [200, { Rack::CONTENT_TYPE => 'text/html' }, ['']] }
|
26
26
|
builder = Rack::Builder.new
|
27
27
|
yield builder if block_given?
|
28
28
|
builder.use Rack::Protection, rack_protection_options
|
data/lib/flipper/version.rb
CHANGED
@@ -1,3 +1,13 @@
|
|
1
1
|
module Flipper
|
2
|
-
VERSION = '1.
|
2
|
+
VERSION = '1.2.0'.freeze
|
3
|
+
|
4
|
+
REQUIRED_RUBY_VERSION = '2.6'.freeze
|
5
|
+
NEXT_REQUIRED_RUBY_VERSION = '3.0'.freeze
|
6
|
+
|
7
|
+
REQUIRED_RAILS_VERSION = '5.2'.freeze
|
8
|
+
NEXT_REQUIRED_RAILS_VERSION = '6.1.0'.freeze
|
9
|
+
|
10
|
+
def self.deprecated_ruby_version?
|
11
|
+
Gem::Version.new(RUBY_VERSION) < Gem::Version.new(NEXT_REQUIRED_RUBY_VERSION)
|
12
|
+
end
|
3
13
|
end
|
@@ -68,7 +68,7 @@ RSpec.describe Flipper::UI::Actions::ActorsGate do
|
|
68
68
|
|
69
69
|
it 'redirects back to feature' do
|
70
70
|
expect(last_response.status).to be(302)
|
71
|
-
expect(last_response.headers['
|
71
|
+
expect(last_response.headers['location']).to eq('/features/search')
|
72
72
|
end
|
73
73
|
|
74
74
|
context "when feature name contains space" do
|
@@ -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['
|
87
|
+
expect(last_response.headers['location']).to eq('/features/sp%20ace')
|
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['
|
117
|
+
expect(last_response.headers['location']).to eq('/features/search/actors?error=%22%22%20is%20not%20a%20valid%20actor%20value.')
|
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['
|
126
|
+
expect(last_response.headers['location']).to eq('/features/search/actors?error=%22%22%20is%20not%20a%20valid%20actor%20value.')
|
127
127
|
end
|
128
128
|
end
|
129
129
|
end
|
@@ -175,7 +175,7 @@ RSpec.describe Flipper::UI::Actions::ActorsGate do
|
|
175
175
|
|
176
176
|
it 'redirects back to feature' do
|
177
177
|
expect(last_response.status).to be(302)
|
178
|
-
expect(last_response.headers['
|
178
|
+
expect(last_response.headers['location']).to eq('/features/search')
|
179
179
|
end
|
180
180
|
|
181
181
|
context 'value contains whitespace' do
|
@@ -25,7 +25,7 @@ RSpec.describe Flipper::UI::Actions::BooleanGate do
|
|
25
25
|
|
26
26
|
it 'redirects back to feature' do
|
27
27
|
expect(last_response.status).to be(302)
|
28
|
-
expect(last_response.headers['
|
28
|
+
expect(last_response.headers['location']).to eq('/features/search')
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -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['
|
46
|
+
expect(last_response.headers['location']).to eq('/features/sp%20ace')
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -61,7 +61,7 @@ RSpec.describe Flipper::UI::Actions::BooleanGate do
|
|
61
61
|
|
62
62
|
it 'redirects back to feature' do
|
63
63
|
expect(last_response.status).to be(302)
|
64
|
-
expect(last_response.headers['
|
64
|
+
expect(last_response.headers['location']).to eq('/features/search')
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
@@ -33,12 +33,12 @@ RSpec.describe Flipper::UI::Actions::Features do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'sets content disposition' do
|
36
|
-
expect(last_response.headers['
|
36
|
+
expect(last_response.headers['content-disposition']).to match(/Attachment;filename=flipper_memory_[0-9]*\.json/)
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'renders json' do
|
40
40
|
data = JSON.parse(last_response.body)
|
41
|
-
expect(last_response.headers['
|
41
|
+
expect(last_response.headers['content-type']).to eq('application/json')
|
42
42
|
expect(data['version']).to eq(1)
|
43
43
|
expect(data['features']).to eq({
|
44
44
|
"analytics" => {"boolean"=>nil, "expression"=>{"Equal"=>[{"Property"=>["plan"]}, "basic"]}, "groups"=>[], "actors"=>[], "percentage_of_actors"=>nil, "percentage_of_time"=>nil},
|
@@ -24,7 +24,7 @@ RSpec.describe Flipper::UI::Actions::Feature do
|
|
24
24
|
|
25
25
|
it 'redirects to features' do
|
26
26
|
expect(last_response.status).to be(302)
|
27
|
-
expect(last_response.headers['
|
27
|
+
expect(last_response.headers['location']).to eq('/features')
|
28
28
|
end
|
29
29
|
|
30
30
|
context "with space in feature name" do
|
@@ -41,7 +41,7 @@ RSpec.describe Flipper::UI::Actions::Feature do
|
|
41
41
|
|
42
42
|
it 'redirects to features' do
|
43
43
|
expect(last_response.status).to be(302)
|
44
|
-
expect(last_response.headers['
|
44
|
+
expect(last_response.headers['location']).to eq('/features')
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -80,7 +80,7 @@ RSpec.describe Flipper::UI::Actions::Feature do
|
|
80
80
|
|
81
81
|
it 'redirects to features' do
|
82
82
|
expect(last_response.status).to be(302)
|
83
|
-
expect(last_response.headers['
|
83
|
+
expect(last_response.headers['location']).to eq('/features')
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -138,14 +138,35 @@ RSpec.describe Flipper::UI::Actions::Feature do
|
|
138
138
|
}
|
139
139
|
}
|
140
140
|
end
|
141
|
-
|
142
|
-
get '/features/search'
|
143
141
|
end
|
144
142
|
|
145
143
|
it 'renders template with custom actor names' do
|
144
|
+
get '/features/search'
|
146
145
|
expect(last_response.body).to include('Some Actor Name (some_actor_name)')
|
147
146
|
expect(last_response.body).not_to include('Some Other Actor Name')
|
148
147
|
end
|
148
|
+
|
149
|
+
it 'allows basic html' do
|
150
|
+
Flipper::UI.configure do |config|
|
151
|
+
config.actor_names_source = lambda { |_keys|
|
152
|
+
{ "some_actor_name" => '<a href="/users/some_actor_name">Some Actor Name</a>', }
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
get '/features/search'
|
157
|
+
expect(last_response.body).to include('<a href="/users/some_actor_name" rel="nofollow">Some Actor Name</a>')
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'sanitizes dangerous markup' do
|
161
|
+
Flipper::UI.configure do |config|
|
162
|
+
config.actor_names_source = lambda { |_keys|
|
163
|
+
{ "some_actor_name" => '<a href="javascript:alert(\'hello\')">Some Actor Name</a>', }
|
164
|
+
}
|
165
|
+
end
|
166
|
+
|
167
|
+
get '/features/search'
|
168
|
+
expect(last_response.body).not_to include('javascript:alert')
|
169
|
+
end
|
149
170
|
end
|
150
171
|
end
|
151
172
|
|
@@ -104,7 +104,7 @@ RSpec.describe Flipper::UI::Actions::Features do
|
|
104
104
|
|
105
105
|
it 'redirects to feature' do
|
106
106
|
expect(last_response.status).to be(302)
|
107
|
-
expect(last_response.headers['
|
107
|
+
expect(last_response.headers['location']).to eq('/features/notifications_next')
|
108
108
|
end
|
109
109
|
|
110
110
|
context 'feature name has whitespace at beginning and end' do
|
@@ -124,7 +124,7 @@ RSpec.describe Flipper::UI::Actions::Features do
|
|
124
124
|
|
125
125
|
it 'redirects to feature' do
|
126
126
|
expect(last_response.status).to be(302)
|
127
|
-
expect(last_response.headers['
|
127
|
+
expect(last_response.headers['location']).to eq('/features/notifications%20next')
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
@@ -138,7 +138,7 @@ RSpec.describe Flipper::UI::Actions::Features do
|
|
138
138
|
|
139
139
|
it 'redirects back to feature' do
|
140
140
|
expect(last_response.status).to be(302)
|
141
|
-
expect(last_response.headers['
|
141
|
+
expect(last_response.headers['location']).to eq('/features/new?error=%22%22%20is%20not%20a%20valid%20feature%20name.')
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
@@ -151,7 +151,7 @@ RSpec.describe Flipper::UI::Actions::Features do
|
|
151
151
|
|
152
152
|
it 'redirects back to feature' do
|
153
153
|
expect(last_response.status).to be(302)
|
154
|
-
expect(last_response.headers['
|
154
|
+
expect(last_response.headers['location']).to eq('/features/new?error=%22%22%20is%20not%20a%20valid%20feature%20name.')
|
155
155
|
end
|
156
156
|
end
|
157
157
|
end
|
@@ -55,7 +55,7 @@ RSpec.describe Flipper::UI::Actions::GroupsGate do
|
|
55
55
|
|
56
56
|
it 'redirects back to feature' do
|
57
57
|
expect(last_response.status).to be(302)
|
58
|
-
expect(last_response.headers['
|
58
|
+
expect(last_response.headers['location']).to eq('/features/search')
|
59
59
|
end
|
60
60
|
|
61
61
|
context 'feature name contains space' do
|
@@ -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['
|
74
|
+
expect(last_response.headers['location']).to eq('/features/sp%20ace')
|
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['
|
92
|
+
expect(last_response.headers['location']).to eq('/features/search/groups?error=The%20group%20named%20%22not_here%22%20has%20not%20been%20registered.')
|
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['
|
101
|
+
expect(last_response.headers['location']).to eq('/features/search/groups?error=The%20group%20named%20%22%22%20has%20not%20been%20registered.')
|
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['
|
110
|
+
expect(last_response.headers['location']).to eq('/features/search/groups?error=The%20group%20named%20%22%22%20has%20not%20been%20registered.')
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
@@ -129,7 +129,7 @@ RSpec.describe Flipper::UI::Actions::GroupsGate do
|
|
129
129
|
|
130
130
|
it 'redirects back to feature' do
|
131
131
|
expect(last_response.status).to be(302)
|
132
|
-
expect(last_response.headers['
|
132
|
+
expect(last_response.headers['location']).to eq('/features/search')
|
133
133
|
end
|
134
134
|
|
135
135
|
context 'group name contains whitespace' do
|
@@ -8,7 +8,7 @@ RSpec.describe Flipper::UI::Actions::Home do
|
|
8
8
|
|
9
9
|
it 'responds with redirect' do
|
10
10
|
expect(last_response.status).to be(302)
|
11
|
-
expect(last_response.headers['
|
11
|
+
expect(last_response.headers['location']).to eq('/features')
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -35,7 +35,7 @@ RSpec.describe Flipper::UI::Actions::Import do
|
|
35
35
|
|
36
36
|
it 'responds with redirect to settings' do
|
37
37
|
expect(last_response.status).to be(302)
|
38
|
-
expect(last_response.headers['
|
38
|
+
expect(last_response.headers['location']).to eq('/features')
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -24,7 +24,7 @@ RSpec.describe Flipper::UI::Actions::PercentageOfActorsGate do
|
|
24
24
|
|
25
25
|
it 'redirects back to feature' do
|
26
26
|
expect(last_response.status).to be(302)
|
27
|
-
expect(last_response.headers['
|
27
|
+
expect(last_response.headers['location']).to eq('/features/search')
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -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['
|
44
|
+
expect(last_response.headers['location']).to eq('/features/sp%20ace')
|
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['
|
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')
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -24,7 +24,7 @@ RSpec.describe Flipper::UI::Actions::PercentageOfTimeGate do
|
|
24
24
|
|
25
25
|
it 'redirects back to feature' do
|
26
26
|
expect(last_response.status).to be(302)
|
27
|
-
expect(last_response.headers['
|
27
|
+
expect(last_response.headers['location']).to eq('/features/search')
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -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['
|
44
|
+
expect(last_response.headers['location']).to eq('/features/sp%20ace')
|
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['
|
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')
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
data/spec/flipper/ui_spec.rb
CHANGED
@@ -42,7 +42,7 @@ RSpec.describe Flipper::UI do
|
|
42
42
|
{ 'value' => 'User;6', 'operation' => 'enable', 'authenticity_token' => token },
|
43
43
|
'rack.session' => session
|
44
44
|
expect(last_response.status).to be(302)
|
45
|
-
expect(last_response.headers['
|
45
|
+
expect(last_response.headers['location']).to eq('/features/refactor-images')
|
46
46
|
end
|
47
47
|
|
48
48
|
describe 'configure' do
|
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.
|
4
|
+
version: 1.2.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:
|
11
|
+
date: 2024-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -56,14 +56,14 @@ dependencies:
|
|
56
56
|
requirements:
|
57
57
|
- - "~>"
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: 1.
|
59
|
+
version: 1.2.0
|
60
60
|
type: :runtime
|
61
61
|
prerelease: false
|
62
62
|
version_requirements: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
64
|
- - "~>"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: 1.
|
66
|
+
version: 1.2.0
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: erubi
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- lib/flipper/ui/public/js/bootstrap-4.6.0.min.js
|
140
140
|
- lib/flipper/ui/public/js/jquery-3.6.0.slim.js
|
141
141
|
- lib/flipper/ui/public/js/popper-1.12.9.min.js
|
142
|
+
- lib/flipper/ui/public/js/version.js
|
142
143
|
- lib/flipper/ui/util.rb
|
143
144
|
- lib/flipper/ui/views/add_actor.erb
|
144
145
|
- lib/flipper/ui/views/add_feature.erb
|
@@ -178,7 +179,7 @@ metadata:
|
|
178
179
|
homepage_uri: https://www.flippercloud.io
|
179
180
|
source_code_uri: https://github.com/flippercloud/flipper
|
180
181
|
bug_tracker_uri: https://github.com/flippercloud/flipper/issues
|
181
|
-
changelog_uri: https://github.com/flippercloud/flipper/
|
182
|
+
changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.2.0
|
182
183
|
post_install_message:
|
183
184
|
rdoc_options: []
|
184
185
|
require_paths:
|
@@ -194,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
195
|
- !ruby/object:Gem::Version
|
195
196
|
version: '0'
|
196
197
|
requirements: []
|
197
|
-
rubygems_version: 3.
|
198
|
+
rubygems_version: 3.5.3
|
198
199
|
signing_key:
|
199
200
|
specification_version: 4
|
200
201
|
summary: Feature flag UI for the Flipper gem
|