flipper-ui 0.2.0.beta2 → 0.2.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +12 -11
  3. data/README.md +5 -7
  4. data/examples/basic.ru +27 -26
  5. data/flipper-ui.gemspec +5 -3
  6. data/lib/flipper-ui.rb +1 -0
  7. data/lib/flipper/ui.rb +11 -2
  8. data/lib/flipper/ui/action.rb +45 -4
  9. data/lib/flipper/ui/actions/actors_gate.rb +48 -0
  10. data/lib/flipper/ui/actions/add_feature.rb +20 -0
  11. data/lib/flipper/ui/actions/boolean_gate.rb +26 -0
  12. data/lib/flipper/ui/actions/feature.rb +32 -0
  13. data/lib/flipper/ui/actions/features.rb +23 -3
  14. data/lib/flipper/ui/actions/file.rb +1 -1
  15. data/lib/flipper/ui/actions/gate.rb +11 -117
  16. data/lib/flipper/ui/actions/groups_gate.rb +43 -0
  17. data/lib/flipper/ui/actions/{index.rb → home.rb} +3 -3
  18. data/lib/flipper/ui/actions/percentage_of_actors_gate.rb +27 -0
  19. data/lib/flipper/ui/actions/percentage_of_time_gate.rb +27 -0
  20. data/lib/flipper/ui/actor.rb +13 -0
  21. data/lib/flipper/ui/assets/javascripts/application.coffee +0 -305
  22. data/lib/flipper/ui/assets/stylesheets/_bootstrap-compass.scss +9 -0
  23. data/lib/flipper/ui/assets/stylesheets/_bootstrap-mincer.scss +19 -0
  24. data/lib/flipper/ui/assets/stylesheets/_bootstrap-sprockets.scss +9 -0
  25. data/lib/flipper/ui/assets/stylesheets/_bootstrap.scss +50 -0
  26. data/lib/flipper/ui/assets/stylesheets/application.scss +33 -216
  27. data/lib/flipper/ui/assets/stylesheets/bootstrap/_alerts.scss +73 -0
  28. data/lib/flipper/ui/assets/stylesheets/bootstrap/_badges.scss +68 -0
  29. data/lib/flipper/ui/assets/stylesheets/bootstrap/_breadcrumbs.scss +26 -0
  30. data/lib/flipper/ui/assets/stylesheets/bootstrap/_button-groups.scss +243 -0
  31. data/lib/flipper/ui/assets/stylesheets/bootstrap/_buttons.scss +160 -0
  32. data/lib/flipper/ui/assets/stylesheets/bootstrap/_carousel.scss +269 -0
  33. data/lib/flipper/ui/assets/stylesheets/bootstrap/_close.scss +36 -0
  34. data/lib/flipper/ui/assets/stylesheets/bootstrap/_code.scss +69 -0
  35. data/lib/flipper/ui/assets/stylesheets/bootstrap/_component-animations.scss +37 -0
  36. data/lib/flipper/ui/assets/stylesheets/bootstrap/_dropdowns.scss +214 -0
  37. data/lib/flipper/ui/assets/stylesheets/bootstrap/_forms.scss +578 -0
  38. data/lib/flipper/ui/assets/stylesheets/bootstrap/_glyphicons.scss +305 -0
  39. data/lib/flipper/ui/assets/stylesheets/bootstrap/_grid.scss +84 -0
  40. data/lib/flipper/ui/assets/stylesheets/bootstrap/_input-groups.scss +166 -0
  41. data/lib/flipper/ui/assets/stylesheets/bootstrap/_jumbotron.scss +50 -0
  42. data/lib/flipper/ui/assets/stylesheets/bootstrap/_labels.scss +66 -0
  43. data/lib/flipper/ui/assets/stylesheets/bootstrap/_list-group.scss +124 -0
  44. data/lib/flipper/ui/assets/stylesheets/bootstrap/_media.scss +61 -0
  45. data/lib/flipper/ui/assets/stylesheets/bootstrap/_mixins.scss +39 -0
  46. data/lib/flipper/ui/assets/stylesheets/bootstrap/_modals.scss +150 -0
  47. data/lib/flipper/ui/assets/stylesheets/bootstrap/_navbar.scss +662 -0
  48. data/lib/flipper/ui/assets/stylesheets/bootstrap/_navs.scss +242 -0
  49. data/lib/flipper/ui/assets/stylesheets/bootstrap/_normalize.scss +427 -0
  50. data/lib/flipper/ui/assets/stylesheets/bootstrap/_pager.scss +54 -0
  51. data/lib/flipper/ui/assets/stylesheets/bootstrap/_pagination.scss +88 -0
  52. data/lib/flipper/ui/assets/stylesheets/bootstrap/_panels.scss +265 -0
  53. data/lib/flipper/ui/assets/stylesheets/bootstrap/_popovers.scss +135 -0
  54. data/lib/flipper/ui/assets/stylesheets/bootstrap/_print.scss +107 -0
  55. data/lib/flipper/ui/assets/stylesheets/bootstrap/_progress-bars.scss +87 -0
  56. data/lib/flipper/ui/assets/stylesheets/bootstrap/_responsive-embed.scss +35 -0
  57. data/lib/flipper/ui/assets/stylesheets/bootstrap/_responsive-utilities.scss +177 -0
  58. data/lib/flipper/ui/assets/stylesheets/bootstrap/_scaffolding.scss +162 -0
  59. data/lib/flipper/ui/assets/stylesheets/bootstrap/_tables.scss +234 -0
  60. data/lib/flipper/ui/assets/stylesheets/bootstrap/_theme.scss +273 -0
  61. data/lib/flipper/ui/assets/stylesheets/bootstrap/_thumbnails.scss +38 -0
  62. data/lib/flipper/ui/assets/stylesheets/bootstrap/_tooltip.scss +102 -0
  63. data/lib/flipper/ui/assets/stylesheets/bootstrap/_type.scss +298 -0
  64. data/lib/flipper/ui/assets/stylesheets/bootstrap/_utilities.scss +55 -0
  65. data/lib/flipper/ui/assets/stylesheets/bootstrap/_variables.scss +866 -0
  66. data/lib/flipper/ui/assets/stylesheets/bootstrap/_wells.scss +29 -0
  67. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_alerts.scss +14 -0
  68. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_background-variant.scss +11 -0
  69. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_border-radius.scss +18 -0
  70. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_buttons.scss +52 -0
  71. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_center-block.scss +7 -0
  72. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_clearfix.scss +22 -0
  73. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_forms.scss +88 -0
  74. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_gradients.scss +58 -0
  75. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +81 -0
  76. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_grid.scss +122 -0
  77. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_hide-text.scss +21 -0
  78. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_image.scss +33 -0
  79. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_labels.scss +12 -0
  80. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_list-group.scss +31 -0
  81. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +10 -0
  82. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_nav-vertical-align.scss +9 -0
  83. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_opacity.scss +8 -0
  84. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_pagination.scss +23 -0
  85. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_panels.scss +24 -0
  86. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_progress-bar.scss +10 -0
  87. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_reset-filter.scss +8 -0
  88. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_resize.scss +6 -0
  89. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss +21 -0
  90. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_size.scss +10 -0
  91. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_tab-focus.scss +9 -0
  92. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_table-row.scss +28 -0
  93. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +11 -0
  94. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_text-overflow.scss +8 -0
  95. data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss +222 -0
  96. data/lib/flipper/ui/assets/stylesheets/primer/.scss-lint.yml +446 -0
  97. data/lib/flipper/ui/assets/stylesheets/primer/_alerts.scss +106 -0
  98. data/lib/flipper/ui/assets/stylesheets/primer/_avatars.scss +36 -0
  99. data/lib/flipper/ui/assets/stylesheets/primer/_base.scss +40 -0
  100. data/lib/flipper/ui/assets/stylesheets/primer/_blankslate.scss +96 -0
  101. data/lib/flipper/ui/assets/stylesheets/primer/_buttons.scss +404 -0
  102. data/lib/flipper/ui/assets/stylesheets/primer/_counter.scss +10 -0
  103. data/lib/flipper/ui/assets/stylesheets/primer/_filter-list.scss +68 -0
  104. data/lib/flipper/ui/assets/stylesheets/primer/_flex-table.scss +20 -0
  105. data/lib/flipper/ui/assets/stylesheets/primer/_forms.scss +756 -0
  106. data/lib/flipper/ui/assets/stylesheets/primer/_layout.scss +69 -0
  107. data/lib/flipper/ui/assets/stylesheets/primer/_menu.scss +113 -0
  108. data/lib/flipper/ui/assets/stylesheets/primer/_mixins.scss +53 -0
  109. data/lib/flipper/ui/assets/stylesheets/primer/_normalize.scss +425 -0
  110. data/lib/flipper/ui/assets/stylesheets/primer/_states.scss +32 -0
  111. data/lib/flipper/ui/assets/stylesheets/primer/_tabnav.scss +65 -0
  112. data/lib/flipper/ui/assets/stylesheets/primer/_tooltips.scss +255 -0
  113. data/lib/flipper/ui/assets/stylesheets/primer/_truncate.scss +27 -0
  114. data/lib/flipper/ui/assets/stylesheets/primer/_type.scss +92 -0
  115. data/lib/flipper/ui/assets/stylesheets/primer/_utility.scss +73 -0
  116. data/lib/flipper/ui/assets/stylesheets/primer/_variables.scss +34 -0
  117. data/lib/flipper/ui/assets/stylesheets/primer/primer.scss +39 -0
  118. data/lib/flipper/ui/decorators/feature.rb +37 -4
  119. data/lib/flipper/ui/middleware.rb +12 -3
  120. data/lib/flipper/ui/public/css/application.css +2563 -144
  121. data/lib/flipper/ui/public/css/primer.css +1 -0
  122. data/lib/flipper/ui/public/css/primer/primer.css +1933 -0
  123. data/lib/flipper/ui/public/css/scss/primer.css +1933 -0
  124. data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.eot +0 -0
  125. data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.svg +288 -0
  126. data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.ttf +0 -0
  127. data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.woff +0 -0
  128. data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.woff2 +0 -0
  129. data/lib/flipper/ui/public/js/application.js +0 -539
  130. data/lib/flipper/ui/public/js/bootstrap-sprockets.js +12 -0
  131. data/lib/flipper/ui/public/js/bootstrap.js +2317 -0
  132. data/lib/flipper/ui/public/js/bootstrap.min.js +7 -0
  133. data/lib/flipper/ui/public/js/bootstrap/affix.js +162 -0
  134. data/lib/flipper/ui/public/js/bootstrap/alert.js +94 -0
  135. data/lib/flipper/ui/public/js/bootstrap/button.js +116 -0
  136. data/lib/flipper/ui/public/js/bootstrap/carousel.js +237 -0
  137. data/lib/flipper/ui/public/js/bootstrap/collapse.js +211 -0
  138. data/lib/flipper/ui/public/js/bootstrap/dropdown.js +161 -0
  139. data/lib/flipper/ui/public/js/bootstrap/modal.js +339 -0
  140. data/lib/flipper/ui/public/js/bootstrap/popover.js +108 -0
  141. data/lib/flipper/ui/public/js/bootstrap/scrollspy.js +172 -0
  142. data/lib/flipper/ui/public/js/bootstrap/tab.js +153 -0
  143. data/lib/flipper/ui/public/js/bootstrap/tooltip.js +476 -0
  144. data/lib/flipper/ui/public/js/bootstrap/transition.js +59 -0
  145. data/lib/flipper/ui/public/octicons/LICENSE.txt +9 -0
  146. data/lib/flipper/ui/public/octicons/README.md +1 -0
  147. data/lib/flipper/ui/public/octicons/octicons-local.ttf +0 -0
  148. data/lib/flipper/ui/public/octicons/octicons.css +236 -0
  149. data/lib/flipper/ui/public/octicons/octicons.eot +0 -0
  150. data/lib/flipper/ui/public/octicons/octicons.less +235 -0
  151. data/lib/flipper/ui/public/octicons/octicons.svg +200 -0
  152. data/lib/flipper/ui/public/octicons/octicons.ttf +0 -0
  153. data/lib/flipper/ui/public/octicons/octicons.woff +0 -0
  154. data/lib/flipper/ui/public/octicons/sprockets-octicons.scss +232 -0
  155. data/lib/flipper/ui/util.rb +4 -0
  156. data/lib/flipper/ui/version.rb +1 -1
  157. data/lib/flipper/ui/views/add_actor.erb +22 -0
  158. data/lib/flipper/ui/views/add_feature.erb +18 -0
  159. data/lib/flipper/ui/views/add_group.erb +31 -0
  160. data/lib/flipper/ui/views/feature.erb +209 -0
  161. data/lib/flipper/ui/views/features.erb +46 -0
  162. data/lib/flipper/ui/views/layout.erb +31 -149
  163. data/script/release +15 -0
  164. data/spec/flipper/ui/actions/actors_gate_spec.rb +68 -0
  165. data/spec/flipper/ui/actions/add_feature_spec.rb +17 -0
  166. data/spec/flipper/ui/actions/boolean_gate_spec.rb +41 -0
  167. data/spec/flipper/ui/actions/feature_spec.rb +59 -0
  168. data/spec/flipper/ui/actions/features_spec.rb +37 -0
  169. data/spec/flipper/ui/actions/file_spec.rb +43 -0
  170. data/spec/flipper/ui/actions/gate_spec.rb +24 -0
  171. data/spec/flipper/ui/actions/groups_gate_spec.rb +80 -0
  172. data/spec/flipper/ui/actions/home_spec.rb +16 -0
  173. data/spec/flipper/ui/actions/percentage_of_actors_gate_spec.rb +40 -0
  174. data/spec/flipper/ui/actions/percentage_of_time_gate_spec.rb +39 -0
  175. data/spec/flipper/ui/decorators/feature_spec.rb +38 -1
  176. data/spec/flipper/ui/decorators/gate_spec.rb +1 -1
  177. data/spec/flipper/ui_spec.rb +18 -441
  178. data/spec/helper.rb +22 -7
  179. metadata +199 -52
  180. data/examples/flipper.html +0 -14
  181. data/examples/flipper.png +0 -0
  182. data/lib/flipper/ui/assets/javascripts/spine/ajax.coffee +0 -223
  183. data/lib/flipper/ui/assets/javascripts/spine/list.coffee +0 -43
  184. data/lib/flipper/ui/assets/javascripts/spine/local.coffee +0 -16
  185. data/lib/flipper/ui/assets/javascripts/spine/manager.coffee +0 -83
  186. data/lib/flipper/ui/assets/javascripts/spine/relation.coffee +0 -148
  187. data/lib/flipper/ui/assets/javascripts/spine/route.coffee +0 -146
  188. data/lib/flipper/ui/assets/javascripts/spine/spine.coffee +0 -542
  189. data/lib/flipper/ui/assets/javascripts/spine/version +0 -1
  190. data/lib/flipper/ui/public/css/images/animated-overlay.gif +0 -0
  191. data/lib/flipper/ui/public/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  192. data/lib/flipper/ui/public/css/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  193. data/lib/flipper/ui/public/css/images/ui-bg_flat_10_000000_40x100.png +0 -0
  194. data/lib/flipper/ui/public/css/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  195. data/lib/flipper/ui/public/css/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  196. data/lib/flipper/ui/public/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  197. data/lib/flipper/ui/public/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  198. data/lib/flipper/ui/public/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  199. data/lib/flipper/ui/public/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  200. data/lib/flipper/ui/public/css/images/ui-icons_222222_256x240.png +0 -0
  201. data/lib/flipper/ui/public/css/images/ui-icons_228ef1_256x240.png +0 -0
  202. data/lib/flipper/ui/public/css/images/ui-icons_ef8c08_256x240.png +0 -0
  203. data/lib/flipper/ui/public/css/images/ui-icons_ffd27a_256x240.png +0 -0
  204. data/lib/flipper/ui/public/css/images/ui-icons_ffffff_256x240.png +0 -0
  205. data/lib/flipper/ui/public/css/jquery-ui-1.10.3.slider.min.css +0 -5
  206. data/lib/flipper/ui/public/js/handlebars.js +0 -1992
  207. data/lib/flipper/ui/public/js/jquery-ui-1.10.3.slider.min.js +0 -6
  208. data/lib/flipper/ui/public/js/jquery.js +0 -9555
  209. data/lib/flipper/ui/public/js/jquery.min.js +0 -4
  210. data/lib/flipper/ui/public/js/jquery.min.map +0 -1
  211. data/lib/flipper/ui/public/js/spine/ajax.js +0 -320
  212. data/lib/flipper/ui/public/js/spine/list.js +0 -72
  213. data/lib/flipper/ui/public/js/spine/local.js +0 -29
  214. data/lib/flipper/ui/public/js/spine/manager.js +0 -157
  215. data/lib/flipper/ui/public/js/spine/relation.js +0 -260
  216. data/lib/flipper/ui/public/js/spine/route.js +0 -223
  217. data/lib/flipper/ui/public/js/spine/spine.js +0 -927
  218. data/lib/flipper/ui/views/index.erb +0 -9
@@ -0,0 +1,15 @@
1
+ #!/bin/sh
2
+ #/ Usage: release
3
+ #/
4
+ #/ Package and release the gem to rubyforge.
5
+ #/
6
+
7
+ set -e
8
+ cd $(dirname "$0")/..
9
+
10
+ [ "$1" = "--help" -o "$1" = "-h" -o "$1" = "help" ] && {
11
+ grep '^#/' <"$0"| cut -c4-
12
+ exit 0
13
+ }
14
+
15
+ script/bootstrap && bundle exec rake release
@@ -0,0 +1,68 @@
1
+ require 'helper'
2
+ require 'flipper/ui/actor'
3
+
4
+ describe Flipper::UI::Actions::ActorsGate do
5
+ describe "GET /features/:feature/actors" do
6
+ before do
7
+ get "features/search/actors"
8
+ end
9
+
10
+ it "responds with success" do
11
+ last_response.status.should be(200)
12
+ end
13
+
14
+ it "renders add new actor form" do
15
+ last_response.body.should include('<form action="/features/search/actors" method="post">')
16
+ end
17
+ end
18
+
19
+ describe "POST /features/:feature/actors" do
20
+ context "enabling an actor" do
21
+ before do
22
+ post "features/search/actors",
23
+ {"value" => "User:6", "operation" => "enable", "authenticity_token" => "a"},
24
+ "rack.session" => {:csrf => "a"}
25
+ end
26
+
27
+ it "adds item to members" do
28
+ flipper[:search].actors_value.should include("User:6")
29
+ end
30
+
31
+ it "redirects back to feature" do
32
+ last_response.status.should be(302)
33
+ last_response.headers["Location"].should eq("/features/search")
34
+ end
35
+ end
36
+
37
+ context "disabling an actor" do
38
+ before do
39
+ flipper[:search].enable_actor Flipper::UI::Actor.new("User:6")
40
+ post "features/search/actors",
41
+ {"value" => "User:6", "operation" => "disable", "authenticity_token" => "a"},
42
+ "rack.session" => {:csrf => "a"}
43
+ end
44
+
45
+ it "removes item from members" do
46
+ flipper[:search].actors_value.should_not include("User:6")
47
+ end
48
+
49
+ it "redirects back to feature" do
50
+ last_response.status.should be(302)
51
+ last_response.headers["Location"].should eq("/features/search")
52
+ end
53
+ end
54
+
55
+ context "for an invalid actor value" do
56
+ before do
57
+ post "features/search/actors",
58
+ {"value" => "", "operation" => "enable", "authenticity_token" => "a"},
59
+ "rack.session" => {:csrf => "a"}
60
+ end
61
+
62
+ it "redirects back to feature" do
63
+ last_response.status.should be(302)
64
+ last_response.headers["Location"].should eq("/features/search/actors?error=%22%22+is+not+a+valid+actor+value.")
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,17 @@
1
+ require 'helper'
2
+
3
+ describe Flipper::UI::Actions::AddFeature do
4
+ describe "GET /features/new" do
5
+ before do
6
+ get "/features/new"
7
+ end
8
+
9
+ it "responds with success" do
10
+ last_response.status.should be(200)
11
+ end
12
+
13
+ it "renders template" do
14
+ last_response.body.should include('<form action="/features" method="post">')
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ require 'helper'
2
+
3
+ describe Flipper::UI::Actions::BooleanGate do
4
+ describe "POST /features/:feature/boolean" do
5
+ context "with enable" do
6
+ before do
7
+ flipper.disable :search
8
+ post "features/search/boolean",
9
+ {"action" => "Enable", "authenticity_token" => "a"},
10
+ "rack.session" => {:csrf => "a"}
11
+ end
12
+
13
+ it "enables the feature" do
14
+ flipper.enabled?(:search).should be(true)
15
+ end
16
+
17
+ it "redirects back to feature" do
18
+ last_response.status.should be(302)
19
+ last_response.headers["Location"].should eq("/features/search")
20
+ end
21
+ end
22
+
23
+ context "with disable" do
24
+ before do
25
+ flipper.enable :search
26
+ post "features/search/boolean",
27
+ {"action" => "Disable", "authenticity_token" => "a"},
28
+ "rack.session" => {:csrf => "a"}
29
+ end
30
+
31
+ it "disables the feature" do
32
+ flipper.enabled?(:search).should be(false)
33
+ end
34
+
35
+ it "redirects back to feature" do
36
+ last_response.status.should be(302)
37
+ last_response.headers["Location"].should eq("/features/search")
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,59 @@
1
+ require 'helper'
2
+
3
+ describe Flipper::UI::Actions::Feature do
4
+ describe "DELETE /features/:feature" do
5
+ before do
6
+ flipper.enable :search
7
+ delete "/features/search",
8
+ {"authenticity_token" => "a"},
9
+ "rack.session" => {:csrf => "a"}
10
+ end
11
+
12
+ it "removes feature" do
13
+ flipper.features.map(&:key).should_not include("search")
14
+ end
15
+
16
+ it "redirects to features" do
17
+ last_response.status.should be(302)
18
+ last_response.headers["Location"].should eq("/features")
19
+ end
20
+ end
21
+
22
+ describe "POST /features/:feature with _method=DELETE" do
23
+ before do
24
+ flipper.enable :search
25
+ post "/features/search",
26
+ {"_method" => "DELETE", "authenticity_token" => "a"},
27
+ "rack.session" => {:csrf => "a"}
28
+ end
29
+
30
+ it "removes feature" do
31
+ flipper.features.map(&:key).should_not include("search")
32
+ end
33
+
34
+ it "redirects to features" do
35
+ last_response.status.should be(302)
36
+ last_response.headers["Location"].should eq("/features")
37
+ end
38
+ end
39
+
40
+ describe "GET /features/:feature" do
41
+ before do
42
+ get "/features/search"
43
+ end
44
+
45
+ it "responds with success" do
46
+ last_response.status.should be(200)
47
+ end
48
+
49
+ it "renders template" do
50
+ last_response.body.should include("search")
51
+ last_response.body.should include("Enable")
52
+ last_response.body.should include("Disable")
53
+ last_response.body.should include("Actors")
54
+ last_response.body.should include("Groups")
55
+ last_response.body.should include("Percentage of Time")
56
+ last_response.body.should include("Percentage of Actors")
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,37 @@
1
+ require 'helper'
2
+
3
+ describe Flipper::UI::Actions::Features do
4
+ describe "GET /features" do
5
+ before do
6
+ flipper[:stats].enable
7
+ flipper[:search].enable
8
+ get "/features"
9
+ end
10
+
11
+ it "responds with success" do
12
+ last_response.status.should be(200)
13
+ end
14
+
15
+ it "renders template" do
16
+ last_response.body.should include("stats")
17
+ last_response.body.should include("search")
18
+ end
19
+ end
20
+
21
+ describe "POST /features" do
22
+ before do
23
+ post "/features",
24
+ {"value" => "notifications_next", "authenticity_token" => "a"},
25
+ "rack.session" => {:csrf => "a"}
26
+ end
27
+
28
+ it "adds feature" do
29
+ flipper.features.map(&:key).should include("notifications_next")
30
+ end
31
+
32
+ it "redirects to features" do
33
+ last_response.status.should be(302)
34
+ last_response.headers["Location"].should eq("/features")
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ require 'helper'
2
+
3
+ describe Flipper::UI::Actions::File do
4
+ describe "GET /images/logo.png" do
5
+ before do
6
+ get '/images/logo.png'
7
+ end
8
+
9
+ it "responds with 200" do
10
+ last_response.status.should be(200)
11
+ end
12
+ end
13
+
14
+ describe "GET /css/application.css" do
15
+ before do
16
+ get '/css/application.css'
17
+ end
18
+
19
+ it "responds with 200" do
20
+ last_response.status.should be(200)
21
+ end
22
+ end
23
+
24
+ describe "GET /fonts/bootstrap/glyphicons-halflings-regular.eot" do
25
+ before do
26
+ get '/fonts/bootstrap/glyphicons-halflings-regular.eot'
27
+ end
28
+
29
+ it "responds with 200" do
30
+ last_response.status.should be(200)
31
+ end
32
+ end
33
+
34
+ describe "GET /octicons/octicons.eot" do
35
+ before do
36
+ get '/octicons/octicons.eot'
37
+ end
38
+
39
+ it "responds with 200" do
40
+ last_response.status.should be(200)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,24 @@
1
+ require 'helper'
2
+
3
+ describe Flipper::UI::Actions::Gate do
4
+ describe "POST /features/:feature/non-existent-gate" do
5
+ before do
6
+ post "/features/search/non-existent-gate",
7
+ {"authenticity_token" => "a"},
8
+ "rack.session" => {:csrf => "a"}
9
+ end
10
+
11
+ it "responds with redirect" do
12
+ last_response.status.should be(302)
13
+ end
14
+
15
+ it "escapes error message" do
16
+ last_response.headers["Location"].should eq("/features/search?error=%22non-existent-gate%22+gate+does+not+exist+therefore+it+cannot+be+updated.")
17
+ end
18
+
19
+ it "renders error in template" do
20
+ follow_redirect!
21
+ last_response.body.should match(/non-existent-gate.*gate does not exist/)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,80 @@
1
+ require 'helper'
2
+
3
+ describe Flipper::UI::Actions::GroupsGate do
4
+ describe "GET /features/:feature/groups" do
5
+ before do
6
+ Flipper.register(:admins) { |user| user.admin? }
7
+ get "features/search/groups"
8
+ end
9
+
10
+ after do
11
+ Flipper.unregister_groups
12
+ end
13
+
14
+ it "responds with success" do
15
+ last_response.status.should be(200)
16
+ end
17
+
18
+ it "renders add new group form" do
19
+ last_response.body.should include('<form action="/features/search/groups" method="post">')
20
+ end
21
+ end
22
+
23
+ describe "POST /features/:feature/groups" do
24
+ before do
25
+ Flipper.register(:admins) { |user| user.admin? }
26
+ end
27
+
28
+ after do
29
+ Flipper.unregister_groups
30
+ end
31
+
32
+ context "enabling a group" do
33
+ before do
34
+ post "features/search/groups",
35
+ {"value" => "admins", "operation" => "enable", "authenticity_token" => "a"},
36
+ "rack.session" => {:csrf => "a"}
37
+ end
38
+
39
+ it "adds item to members" do
40
+ flipper[:search].groups_value.should include("admins")
41
+ end
42
+
43
+ it "redirects back to feature" do
44
+ last_response.status.should be(302)
45
+ last_response.headers["Location"].should eq("/features/search")
46
+ end
47
+ end
48
+
49
+ context "disabling a group" do
50
+ before do
51
+ flipper[:search].enable_group :admins
52
+ post "features/search/groups",
53
+ {"value" => "admins", "operation" => "disable", "authenticity_token" => "a"},
54
+ "rack.session" => {:csrf => "a"}
55
+ end
56
+
57
+ it "removes item from members" do
58
+ flipper[:search].groups_value.should_not include("admins")
59
+ end
60
+
61
+ it "redirects back to feature" do
62
+ last_response.status.should be(302)
63
+ last_response.headers["Location"].should eq("/features/search")
64
+ end
65
+ end
66
+
67
+ context "for an unregistered group" do
68
+ before do
69
+ post "features/search/groups",
70
+ {"value" => "not_here", "operation" => "enable", "authenticity_token" => "a"},
71
+ "rack.session" => {:csrf => "a"}
72
+ end
73
+
74
+ it "redirects back to feature" do
75
+ last_response.status.should be(302)
76
+ last_response.headers["Location"].should eq("/features/search/groups?error=The+group+named+%22not_here%22+has+not+been+registered.")
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,16 @@
1
+ require 'helper'
2
+
3
+ describe Flipper::UI::Actions::Home do
4
+ describe "GET /" do
5
+ before do
6
+ flipper[:stats].enable
7
+ flipper[:search].enable
8
+ get "/"
9
+ end
10
+
11
+ it "responds with redirect" do
12
+ last_response.status.should be(302)
13
+ last_response.headers["Location"].should eq("/features")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+ require 'helper'
2
+ require 'flipper/ui/actor'
3
+
4
+ describe Flipper::UI::Actions::PercentageOfActorsGate do
5
+ describe "POST /features/:feature/percentage_of_actors" do
6
+ context "with valid value" do
7
+ before do
8
+ post "features/search/percentage_of_actors",
9
+ {"value" => "24", "authenticity_token" => "a"},
10
+ "rack.session" => {:csrf => "a"}
11
+ end
12
+
13
+ it "enables the feature" do
14
+ flipper[:search].percentage_of_actors_value.should be(24)
15
+ end
16
+
17
+ it "redirects back to feature" do
18
+ last_response.status.should be(302)
19
+ last_response.headers["Location"].should eq("/features/search")
20
+ end
21
+ end
22
+
23
+ context "with invalid value" do
24
+ before do
25
+ post "features/search/percentage_of_actors",
26
+ {"value" => "555", "authenticity_token" => "a"},
27
+ "rack.session" => {:csrf => "a"}
28
+ end
29
+
30
+ it "does not change value" do
31
+ flipper[:search].percentage_of_actors_value.should be(0)
32
+ end
33
+
34
+ it "redirects back to feature" do
35
+ last_response.status.should be(302)
36
+ last_response.headers["Location"].should 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")
37
+ end
38
+ end
39
+ end
40
+ end