flipper-ui 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|