flipper-ui 0.7.1 → 0.7.2
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/lib/flipper/ui.rb +7 -0
- data/lib/flipper/ui/action.rb +7 -2
- data/lib/flipper/ui/views/layout.erb +1 -1
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/ui/actions/actors_gate_spec.rb +11 -11
- data/spec/flipper/ui/actions/add_feature_spec.rb +3 -3
- data/spec/flipper/ui/actions/boolean_gate_spec.rb +7 -7
- data/spec/flipper/ui/actions/feature_spec.rb +15 -15
- data/spec/flipper/ui/actions/features_spec.rb +7 -7
- data/spec/flipper/ui/actions/file_spec.rb +5 -5
- data/spec/flipper/ui/actions/gate_spec.rb +4 -4
- data/spec/flipper/ui/actions/groups_gate_spec.rb +11 -11
- data/spec/flipper/ui/actions/home_spec.rb +3 -3
- data/spec/flipper/ui/actions/percentage_of_actors_gate_spec.rb +7 -7
- data/spec/flipper/ui/actions/percentage_of_time_gate_spec.rb +7 -7
- data/spec/flipper/ui/decorators/feature_spec.rb +12 -12
- data/spec/flipper/ui/decorators/gate_spec.rb +7 -7
- data/spec/flipper/ui/util_spec.rb +5 -5
- data/spec/flipper/ui_spec.rb +59 -7
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58ff741014c1d7db19e16dbbda8baae1dc292283
|
4
|
+
data.tar.gz: a1b6e435404f69cfff852611f9aa7749d3a48161
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d4e8db0c63c591a067916cb32ba6d137c7901e31a8c9996ad1305764505beb2a71031b1c043dc1803c632778ee4a0a64c81920d9c78e50b7ce9c037c4f44ecd
|
7
|
+
data.tar.gz: 8d5a753a31e86aee0b6d99a60e77b8fbb90e4e76d23a3d7fb737b1abad59ddcfdef4d52e46f8051c03da1389b0b47fc904cf3a72e965d97d4de3df7b9a0067a0
|
data/lib/flipper/ui.rb
CHANGED
@@ -11,6 +11,13 @@ require 'flipper/ui/middleware'
|
|
11
11
|
|
12
12
|
module Flipper
|
13
13
|
module UI
|
14
|
+
class << self
|
15
|
+
# Public: If you set this, the UI will always have a first breadcrumb that
|
16
|
+
# says "App" which points to this href. The href can be a path (ie: "/")
|
17
|
+
# or full url ("https://app.example.com/").
|
18
|
+
attr_accessor :application_breadcrumb_href
|
19
|
+
end
|
20
|
+
|
14
21
|
def self.root
|
15
22
|
@root ||= Pathname(__FILE__).dirname.expand_path.join('ui')
|
16
23
|
end
|
data/lib/flipper/ui/action.rb
CHANGED
@@ -56,7 +56,11 @@ module Flipper
|
|
56
56
|
@flipper, @request = flipper, request
|
57
57
|
@code = 200
|
58
58
|
@headers = {"Content-Type" => "text/plain"}
|
59
|
-
@breadcrumbs =
|
59
|
+
@breadcrumbs = if Flipper::UI.application_breadcrumb_href
|
60
|
+
[Breadcrumb.new("App", Flipper::UI.application_breadcrumb_href)]
|
61
|
+
else
|
62
|
+
[]
|
63
|
+
end
|
60
64
|
end
|
61
65
|
|
62
66
|
# Public: Runs the request method for the provided request.
|
@@ -159,7 +163,8 @@ module Flipper
|
|
159
163
|
# href - The String href for the anchor tag (optional). If nil, breadcrumb
|
160
164
|
# is assumed to be the end of the trail.
|
161
165
|
def breadcrumb(text, href = nil)
|
162
|
-
|
166
|
+
breadcrumb_href = href.nil? ? href : "#{script_name}#{href}"
|
167
|
+
@breadcrumbs << Breadcrumb.new(text, breadcrumb_href)
|
163
168
|
end
|
164
169
|
|
165
170
|
# Private
|
data/lib/flipper/version.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::ActorsGate do
|
3
|
+
RSpec.describe Flipper::UI::Actions::ActorsGate do
|
4
4
|
describe "GET /features/:feature/actors" do
|
5
5
|
before do
|
6
6
|
get "features/search/actors"
|
7
7
|
end
|
8
8
|
|
9
9
|
it "responds with success" do
|
10
|
-
last_response.status.
|
10
|
+
expect(last_response.status).to be(200)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "renders add new actor form" do
|
14
|
-
last_response.body.
|
14
|
+
expect(last_response.body).to include('<form action="/features/search/actors" method="post">')
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -24,12 +24,12 @@ describe Flipper::UI::Actions::ActorsGate do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it "adds item to members" do
|
27
|
-
flipper[:search].actors_value.
|
27
|
+
expect(flipper[:search].actors_value).to include("User:6")
|
28
28
|
end
|
29
29
|
|
30
30
|
it "redirects back to feature" do
|
31
|
-
last_response.status.
|
32
|
-
last_response.headers["Location"].
|
31
|
+
expect(last_response.status).to be(302)
|
32
|
+
expect(last_response.headers["Location"]).to eq("/features/search")
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -42,12 +42,12 @@ describe Flipper::UI::Actions::ActorsGate do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it "removes item from members" do
|
45
|
-
flipper[:search].actors_value.
|
45
|
+
expect(flipper[:search].actors_value).not_to include("User:6")
|
46
46
|
end
|
47
47
|
|
48
48
|
it "redirects back to feature" do
|
49
|
-
last_response.status.
|
50
|
-
last_response.headers["Location"].
|
49
|
+
expect(last_response.status).to be(302)
|
50
|
+
expect(last_response.headers["Location"]).to eq("/features/search")
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -59,8 +59,8 @@ describe Flipper::UI::Actions::ActorsGate do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
it "redirects back to feature" do
|
62
|
-
last_response.status.
|
63
|
-
last_response.headers["Location"].
|
62
|
+
expect(last_response.status).to be(302)
|
63
|
+
expect(last_response.headers["Location"]).to eq("/features/search/actors?error=%22%22+is+not+a+valid+actor+value.")
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::AddFeature do
|
3
|
+
RSpec.describe Flipper::UI::Actions::AddFeature do
|
4
4
|
describe "GET /features/new" do
|
5
5
|
before do
|
6
6
|
get "/features/new"
|
7
7
|
end
|
8
8
|
|
9
9
|
it "responds with success" do
|
10
|
-
last_response.status.
|
10
|
+
expect(last_response.status).to be(200)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "renders template" do
|
14
|
-
last_response.body.
|
14
|
+
expect(last_response.body).to include('<form action="/features" method="post">')
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::BooleanGate do
|
3
|
+
RSpec.describe Flipper::UI::Actions::BooleanGate do
|
4
4
|
describe "POST /features/:feature/boolean" do
|
5
5
|
context "with enable" do
|
6
6
|
before do
|
@@ -11,12 +11,12 @@ describe Flipper::UI::Actions::BooleanGate do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it "enables the feature" do
|
14
|
-
flipper.enabled?(:search).
|
14
|
+
expect(flipper.enabled?(:search)).to be(true)
|
15
15
|
end
|
16
16
|
|
17
17
|
it "redirects back to feature" do
|
18
|
-
last_response.status.
|
19
|
-
last_response.headers["Location"].
|
18
|
+
expect(last_response.status).to be(302)
|
19
|
+
expect(last_response.headers["Location"]).to eq("/features/search")
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -29,12 +29,12 @@ describe Flipper::UI::Actions::BooleanGate do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "disables the feature" do
|
32
|
-
flipper.enabled?(:search).
|
32
|
+
expect(flipper.enabled?(:search)).to be(false)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "redirects back to feature" do
|
36
|
-
last_response.status.
|
37
|
-
last_response.headers["Location"].
|
36
|
+
expect(last_response.status).to be(302)
|
37
|
+
expect(last_response.headers["Location"]).to eq("/features/search")
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::Feature do
|
3
|
+
RSpec.describe Flipper::UI::Actions::Feature do
|
4
4
|
describe "DELETE /features/:feature" do
|
5
5
|
before do
|
6
6
|
flipper.enable :search
|
@@ -10,12 +10,12 @@ describe Flipper::UI::Actions::Feature do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "removes feature" do
|
13
|
-
flipper.features.map(&:key).
|
13
|
+
expect(flipper.features.map(&:key)).not_to include("search")
|
14
14
|
end
|
15
15
|
|
16
16
|
it "redirects to features" do
|
17
|
-
last_response.status.
|
18
|
-
last_response.headers["Location"].
|
17
|
+
expect(last_response.status).to be(302)
|
18
|
+
expect(last_response.headers["Location"]).to eq("/features")
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -28,12 +28,12 @@ describe Flipper::UI::Actions::Feature do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "removes feature" do
|
31
|
-
flipper.features.map(&:key).
|
31
|
+
expect(flipper.features.map(&:key)).not_to include("search")
|
32
32
|
end
|
33
33
|
|
34
34
|
it "redirects to features" do
|
35
|
-
last_response.status.
|
36
|
-
last_response.headers["Location"].
|
35
|
+
expect(last_response.status).to be(302)
|
36
|
+
expect(last_response.headers["Location"]).to eq("/features")
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -43,17 +43,17 @@ describe Flipper::UI::Actions::Feature do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it "responds with success" do
|
46
|
-
last_response.status.
|
46
|
+
expect(last_response.status).to be(200)
|
47
47
|
end
|
48
48
|
|
49
49
|
it "renders template" do
|
50
|
-
last_response.body.
|
51
|
-
last_response.body.
|
52
|
-
last_response.body.
|
53
|
-
last_response.body.
|
54
|
-
last_response.body.
|
55
|
-
last_response.body.
|
56
|
-
last_response.body.
|
50
|
+
expect(last_response.body).to include("search")
|
51
|
+
expect(last_response.body).to include("Enable")
|
52
|
+
expect(last_response.body).to include("Disable")
|
53
|
+
expect(last_response.body).to include("Actors")
|
54
|
+
expect(last_response.body).to include("Groups")
|
55
|
+
expect(last_response.body).to include("Percentage of Time")
|
56
|
+
expect(last_response.body).to include("Percentage of Actors")
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::Features do
|
3
|
+
RSpec.describe Flipper::UI::Actions::Features do
|
4
4
|
describe "GET /features" do
|
5
5
|
before do
|
6
6
|
flipper[:stats].enable
|
@@ -9,12 +9,12 @@ describe Flipper::UI::Actions::Features do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "responds with success" do
|
12
|
-
last_response.status.
|
12
|
+
expect(last_response.status).to be(200)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "renders template" do
|
16
|
-
last_response.body.
|
17
|
-
last_response.body.
|
16
|
+
expect(last_response.body).to include("stats")
|
17
|
+
expect(last_response.body).to include("search")
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -26,12 +26,12 @@ describe Flipper::UI::Actions::Features do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it "adds feature" do
|
29
|
-
flipper.features.map(&:key).
|
29
|
+
expect(flipper.features.map(&:key)).to include("notifications_next")
|
30
30
|
end
|
31
31
|
|
32
32
|
it "redirects to feature" do
|
33
|
-
last_response.status.
|
34
|
-
last_response.headers["Location"].
|
33
|
+
expect(last_response.status).to be(302)
|
34
|
+
expect(last_response.headers["Location"]).to eq("/features/notifications_next")
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::File do
|
3
|
+
RSpec.describe Flipper::UI::Actions::File do
|
4
4
|
describe "GET /images/logo.png" do
|
5
5
|
before do
|
6
6
|
get '/images/logo.png'
|
7
7
|
end
|
8
8
|
|
9
9
|
it "responds with 200" do
|
10
|
-
last_response.status.
|
10
|
+
expect(last_response.status).to be(200)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -17,7 +17,7 @@ describe Flipper::UI::Actions::File do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "responds with 200" do
|
20
|
-
last_response.status.
|
20
|
+
expect(last_response.status).to be(200)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -27,7 +27,7 @@ describe Flipper::UI::Actions::File do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it "responds with 200" do
|
30
|
-
last_response.status.
|
30
|
+
expect(last_response.status).to be(200)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -37,7 +37,7 @@ describe Flipper::UI::Actions::File do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "responds with 200" do
|
40
|
-
last_response.status.
|
40
|
+
expect(last_response.status).to be(200)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::Gate do
|
3
|
+
RSpec.describe Flipper::UI::Actions::Gate do
|
4
4
|
describe "POST /features/:feature/non-existent-gate" do
|
5
5
|
before do
|
6
6
|
post "/features/search/non-existent-gate",
|
@@ -9,16 +9,16 @@ describe Flipper::UI::Actions::Gate do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "responds with redirect" do
|
12
|
-
last_response.status.
|
12
|
+
expect(last_response.status).to be(302)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "escapes error message" do
|
16
|
-
last_response.headers["Location"].
|
16
|
+
expect(last_response.headers["Location"]).to eq("/features/search?error=%22non-existent-gate%22+gate+does+not+exist+therefore+it+cannot+be+updated.")
|
17
17
|
end
|
18
18
|
|
19
19
|
it "renders error in template" do
|
20
20
|
follow_redirect!
|
21
|
-
last_response.body.
|
21
|
+
expect(last_response.body).to match(/non-existent-gate.*gate does not exist/)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::GroupsGate do
|
3
|
+
RSpec.describe Flipper::UI::Actions::GroupsGate do
|
4
4
|
describe "GET /features/:feature/groups" do
|
5
5
|
before do
|
6
6
|
Flipper.register(:admins) { |user| user.admin? }
|
@@ -12,11 +12,11 @@ describe Flipper::UI::Actions::GroupsGate do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "responds with success" do
|
15
|
-
last_response.status.
|
15
|
+
expect(last_response.status).to be(200)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "renders add new group form" do
|
19
|
-
last_response.body.
|
19
|
+
expect(last_response.body).to include('<form action="/features/search/groups" method="post">')
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -37,12 +37,12 @@ describe Flipper::UI::Actions::GroupsGate do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "adds item to members" do
|
40
|
-
flipper[:search].groups_value.
|
40
|
+
expect(flipper[:search].groups_value).to include("admins")
|
41
41
|
end
|
42
42
|
|
43
43
|
it "redirects back to feature" do
|
44
|
-
last_response.status.
|
45
|
-
last_response.headers["Location"].
|
44
|
+
expect(last_response.status).to be(302)
|
45
|
+
expect(last_response.headers["Location"]).to eq("/features/search")
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -55,12 +55,12 @@ describe Flipper::UI::Actions::GroupsGate do
|
|
55
55
|
end
|
56
56
|
|
57
57
|
it "removes item from members" do
|
58
|
-
flipper[:search].groups_value.
|
58
|
+
expect(flipper[:search].groups_value).not_to include("admins")
|
59
59
|
end
|
60
60
|
|
61
61
|
it "redirects back to feature" do
|
62
|
-
last_response.status.
|
63
|
-
last_response.headers["Location"].
|
62
|
+
expect(last_response.status).to be(302)
|
63
|
+
expect(last_response.headers["Location"]).to eq("/features/search")
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
@@ -72,8 +72,8 @@ describe Flipper::UI::Actions::GroupsGate do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
it "redirects back to feature" do
|
75
|
-
last_response.status.
|
76
|
-
last_response.headers["Location"].
|
75
|
+
expect(last_response.status).to be(302)
|
76
|
+
expect(last_response.headers["Location"]).to eq("/features/search/groups?error=The+group+named+%22not_here%22+has+not+been+registered.")
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::Home do
|
3
|
+
RSpec.describe Flipper::UI::Actions::Home do
|
4
4
|
describe "GET /" do
|
5
5
|
before do
|
6
6
|
flipper[:stats].enable
|
@@ -9,8 +9,8 @@ describe Flipper::UI::Actions::Home do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "responds with redirect" do
|
12
|
-
last_response.status.
|
13
|
-
last_response.headers["Location"].
|
12
|
+
expect(last_response.status).to be(302)
|
13
|
+
expect(last_response.headers["Location"]).to eq("/features")
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::PercentageOfActorsGate do
|
3
|
+
RSpec.describe Flipper::UI::Actions::PercentageOfActorsGate do
|
4
4
|
describe "POST /features/:feature/percentage_of_actors" do
|
5
5
|
context "with valid value" do
|
6
6
|
before do
|
@@ -10,12 +10,12 @@ describe Flipper::UI::Actions::PercentageOfActorsGate do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "enables the feature" do
|
13
|
-
flipper[:search].percentage_of_actors_value.
|
13
|
+
expect(flipper[:search].percentage_of_actors_value).to be(24)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "redirects back to feature" do
|
17
|
-
last_response.status.
|
18
|
-
last_response.headers["Location"].
|
17
|
+
expect(last_response.status).to be(302)
|
18
|
+
expect(last_response.headers["Location"]).to eq("/features/search")
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -27,12 +27,12 @@ describe Flipper::UI::Actions::PercentageOfActorsGate do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it "does not change value" do
|
30
|
-
flipper[:search].percentage_of_actors_value.
|
30
|
+
expect(flipper[:search].percentage_of_actors_value).to be(0)
|
31
31
|
end
|
32
32
|
|
33
33
|
it "redirects back to feature" do
|
34
|
-
last_response.status.
|
35
|
-
last_response.headers["Location"].
|
34
|
+
expect(last_response.status).to be(302)
|
35
|
+
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")
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI::Actions::PercentageOfTimeGate do
|
3
|
+
RSpec.describe Flipper::UI::Actions::PercentageOfTimeGate do
|
4
4
|
describe "POST /features/:feature/percentage_of_time" do
|
5
5
|
context "with valid value" do
|
6
6
|
before do
|
@@ -10,12 +10,12 @@ describe Flipper::UI::Actions::PercentageOfTimeGate do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "enables the feature" do
|
13
|
-
flipper[:search].percentage_of_time_value.
|
13
|
+
expect(flipper[:search].percentage_of_time_value).to be(24)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "redirects back to feature" do
|
17
|
-
last_response.status.
|
18
|
-
last_response.headers["Location"].
|
17
|
+
expect(last_response.status).to be(302)
|
18
|
+
expect(last_response.headers["Location"]).to eq("/features/search")
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -27,12 +27,12 @@ describe Flipper::UI::Actions::PercentageOfTimeGate do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it "does not change value" do
|
30
|
-
flipper[:search].percentage_of_time_value.
|
30
|
+
expect(flipper[:search].percentage_of_time_value).to be(0)
|
31
31
|
end
|
32
32
|
|
33
33
|
it "redirects back to feature" do
|
34
|
-
last_response.status.
|
35
|
-
last_response.headers["Location"].
|
34
|
+
expect(last_response.status).to be(302)
|
35
|
+
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")
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/adapters/memory'
|
3
3
|
|
4
|
-
describe Flipper::UI::Decorators::Feature do
|
4
|
+
RSpec.describe Flipper::UI::Decorators::Feature do
|
5
5
|
let(:source) { {} }
|
6
6
|
let(:adapter) { Flipper::Adapters::Memory.new(source) }
|
7
7
|
let(:flipper) { build_flipper }
|
@@ -13,13 +13,13 @@ describe Flipper::UI::Decorators::Feature do
|
|
13
13
|
|
14
14
|
describe "#initialize" do
|
15
15
|
it "sets the feature" do
|
16
|
-
subject.feature.
|
16
|
+
expect(subject.feature).to be(feature)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
describe "#pretty_name" do
|
21
21
|
it "capitalizes each word separated by underscores" do
|
22
|
-
subject.pretty_name.
|
22
|
+
expect(subject.pretty_name).to eq('Some Awesome Feature')
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -29,19 +29,19 @@ describe Flipper::UI::Decorators::Feature do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "returns Hash" do
|
32
|
-
@result.
|
32
|
+
expect(@result).to be_instance_of(Hash)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "includes id" do
|
36
|
-
@result['id'].
|
36
|
+
expect(@result['id']).to eq('some_awesome_feature')
|
37
37
|
end
|
38
38
|
|
39
39
|
it "includes pretty name" do
|
40
|
-
@result['name'].
|
40
|
+
expect(@result['name']).to eq('Some Awesome Feature')
|
41
41
|
end
|
42
42
|
|
43
43
|
it "includes state" do
|
44
|
-
@result['state'].
|
44
|
+
expect(@result['state']).to eq('off')
|
45
45
|
end
|
46
46
|
|
47
47
|
it "includes gates" do
|
@@ -49,7 +49,7 @@ describe Flipper::UI::Decorators::Feature do
|
|
49
49
|
value = subject.gate_values[gate.key]
|
50
50
|
Flipper::UI::Decorators::Gate.new(gate, value).as_json
|
51
51
|
}
|
52
|
-
@result['gates'].
|
52
|
+
expect(@result['gates']).to eq(gates)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -74,19 +74,19 @@ describe Flipper::UI::Decorators::Feature do
|
|
74
74
|
}
|
75
75
|
|
76
76
|
it "sorts :on before :conditional" do
|
77
|
-
(on <=> conditional).
|
77
|
+
expect((on <=> conditional)).to be(-1)
|
78
78
|
end
|
79
79
|
|
80
80
|
it "sorts :on before :off" do
|
81
|
-
(on <=> conditional).
|
81
|
+
expect((on <=> conditional)).to be(-1)
|
82
82
|
end
|
83
83
|
|
84
84
|
it "sorts :conditional before :off" do
|
85
|
-
(on <=> conditional).
|
85
|
+
expect((on <=> conditional)).to be(-1)
|
86
86
|
end
|
87
87
|
|
88
88
|
it "sorts on key for identical states" do
|
89
|
-
(on <=> on_b).
|
89
|
+
expect((on <=> on_b)).to be(-1)
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
@@ -2,7 +2,7 @@ require 'helper'
|
|
2
2
|
require 'flipper/adapters/memory'
|
3
3
|
require 'flipper/ui/decorators/gate'
|
4
4
|
|
5
|
-
describe Flipper::UI::Decorators::Gate do
|
5
|
+
RSpec.describe Flipper::UI::Decorators::Gate do
|
6
6
|
let(:source) { {} }
|
7
7
|
let(:adapter) { Flipper::Adapters::Memory.new(source) }
|
8
8
|
let(:flipper) { build_flipper }
|
@@ -15,11 +15,11 @@ describe Flipper::UI::Decorators::Gate do
|
|
15
15
|
|
16
16
|
describe "#initialize" do
|
17
17
|
it "sets gate" do
|
18
|
-
subject.gate.
|
18
|
+
expect(subject.gate).to be(gate)
|
19
19
|
end
|
20
20
|
|
21
21
|
it "sets value" do
|
22
|
-
subject.value.
|
22
|
+
expect(subject.value).to eq(false)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -29,19 +29,19 @@ describe Flipper::UI::Decorators::Gate do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "returns Hash" do
|
32
|
-
@result.
|
32
|
+
expect(@result).to be_instance_of(Hash)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "includes key" do
|
36
|
-
@result['key'].
|
36
|
+
expect(@result['key']).to eq('boolean')
|
37
37
|
end
|
38
38
|
|
39
39
|
it "includes pretty name" do
|
40
|
-
@result['name'].
|
40
|
+
expect(@result['name']).to eq('boolean')
|
41
41
|
end
|
42
42
|
|
43
43
|
it "includes value" do
|
44
|
-
@result['value'].
|
44
|
+
expect(@result['value']).to be(false)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/ui/util'
|
3
3
|
|
4
|
-
describe Flipper::UI::Util do
|
4
|
+
RSpec.describe Flipper::UI::Util do
|
5
5
|
describe "#blank?" do
|
6
6
|
context "with a string" do
|
7
7
|
it "returns true if blank" do
|
8
|
-
described_class.blank?(nil).
|
9
|
-
described_class.blank?('').
|
10
|
-
described_class.blank?(' ').
|
8
|
+
expect(described_class.blank?(nil)).to be(true)
|
9
|
+
expect(described_class.blank?('')).to be(true)
|
10
|
+
expect(described_class.blank?(' ')).to be(true)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "returns false if not blank" do
|
14
|
-
described_class.blank?('nope').
|
14
|
+
expect(described_class.blank?('nope')).to be(false)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/spec/flipper/ui_spec.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe Flipper::UI do
|
3
|
+
RSpec.describe Flipper::UI do
|
4
4
|
describe "Initializing middleware with flipper instance" do
|
5
5
|
let(:app) { build_app(flipper) }
|
6
6
|
|
7
7
|
it "works" do
|
8
8
|
flipper.enable :some_great_feature
|
9
9
|
get "/features"
|
10
|
-
last_response.status.
|
11
|
-
last_response.body.
|
10
|
+
expect(last_response.status).to be(200)
|
11
|
+
expect(last_response.body).to include("some_great_feature")
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -20,8 +20,8 @@ describe Flipper::UI do
|
|
20
20
|
it "works" do
|
21
21
|
flipper.enable :some_great_feature
|
22
22
|
get "/features"
|
23
|
-
last_response.status.
|
24
|
-
last_response.body.
|
23
|
+
expect(last_response.status).to be(200)
|
24
|
+
expect(last_response.body).to include("some_great_feature")
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -38,7 +38,59 @@ describe Flipper::UI do
|
|
38
38
|
post "features/refactor-images/actors",
|
39
39
|
{"value" => "User:6", "operation" => "enable", "authenticity_token" => "a"},
|
40
40
|
"rack.session" => {:csrf => "a"}
|
41
|
-
last_response.status.
|
42
|
-
last_response.headers["Location"].
|
41
|
+
expect(last_response.status).to be(302)
|
42
|
+
expect(last_response.headers["Location"]).to eq("/features/refactor-images")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not have an application_breadcrumb_href by default" do
|
46
|
+
expect(Flipper::UI.application_breadcrumb_href).to be(nil)
|
47
|
+
end
|
48
|
+
|
49
|
+
context "with application_breadcrumb_href not set" do
|
50
|
+
before do
|
51
|
+
@original_application_breadcrumb_href = Flipper::UI.application_breadcrumb_href
|
52
|
+
Flipper::UI.application_breadcrumb_href = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
after do
|
56
|
+
Flipper::UI.application_breadcrumb_href = @original_application_breadcrumb_href
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'does not add App breadcrumb' do
|
60
|
+
get "/features"
|
61
|
+
expect(last_response.body).to_not include('<a href="/myapp">App</a>')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with application_breadcrumb_href set" do
|
66
|
+
before do
|
67
|
+
@original_application_breadcrumb_href = Flipper::UI.application_breadcrumb_href
|
68
|
+
Flipper::UI.application_breadcrumb_href = "/myapp"
|
69
|
+
end
|
70
|
+
|
71
|
+
after do
|
72
|
+
Flipper::UI.application_breadcrumb_href = @original_application_breadcrumb_href
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'does add App breadcrumb' do
|
76
|
+
get "/features"
|
77
|
+
expect(last_response.body).to include('<a href="/myapp">App</a>')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "with application_breadcrumb_href set to full url" do
|
82
|
+
before do
|
83
|
+
@original_application_breadcrumb_href = Flipper::UI.application_breadcrumb_href
|
84
|
+
Flipper::UI.application_breadcrumb_href = "https://myapp.com/"
|
85
|
+
end
|
86
|
+
|
87
|
+
after do
|
88
|
+
Flipper::UI.application_breadcrumb_href = @original_application_breadcrumb_href
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'does add App breadcrumb' do
|
92
|
+
get "/features"
|
93
|
+
expect(last_response.body).to include('<a href="https://myapp.com/">App</a>')
|
94
|
+
end
|
43
95
|
end
|
44
96
|
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: 0.7.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -50,14 +50,14 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0.7.
|
53
|
+
version: 0.7.2
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0.7.
|
60
|
+
version: 0.7.2
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: erubis
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -283,7 +283,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
283
283
|
version: '0'
|
284
284
|
requirements: []
|
285
285
|
rubyforge_project:
|
286
|
-
rubygems_version: 2.2.
|
286
|
+
rubygems_version: 2.2.2
|
287
287
|
signing_key:
|
288
288
|
specification_version: 4
|
289
289
|
summary: UI for the Flipper gem
|