rack-flags 0.1.4 → 0.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.
@@ -52,7 +52,12 @@ module RackFlags
52
52
  overrides
53
53
  end
54
54
 
55
- response.set_cookie(CookieCodec::COOKIE_KEY, value: CookieCodec.new.generate_cookie_from(overrides), path: '/')
55
+ response.set_cookie(
56
+ CookieCodec::COOKIE_KEY,
57
+ value: CookieCodec.new.generate_cookie_from(overrides),
58
+ path: '/',
59
+ expires: cookie_expiration
60
+ )
56
61
  redirect to('/'), 303
57
62
  end
58
63
 
@@ -67,5 +72,10 @@ module RackFlags
67
72
  flag_states[form_param_flag_state.to_sym]
68
73
  end
69
74
 
75
+ def cookie_expiration
76
+ # store overrides in the cookie for around for ~5 years from the last time they were modified
77
+ Time.new( Time.now.year + 5 )
78
+ end
79
+
70
80
  end
71
81
  end
@@ -1,3 +1,3 @@
1
1
  module RackFlags
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require_relative 'spec_helper'
2
+ require_relative 'support/page_objects/admin_page'
2
3
 
3
4
  describe 'displaying flags in admin app' do
4
- include Capybara::DSL
5
5
 
6
6
  let( :feature_flag_config ) do
7
7
  {
@@ -29,65 +29,41 @@ describe 'displaying flags in admin app' do
29
29
  end
30
30
  end
31
31
 
32
- let(:on_flag_section){ page.find('section[data-flag-name="on_by_default"]') }
33
- let(:off_flag_section){ page.find('section[data-flag-name="off_by_default"]') }
34
- let(:update_button){ page.find('input[type="submit"]') }
35
-
36
32
  it 'successfully GETs the admin page' do
37
- visit '/'
38
- status_code.should == 200
33
+ AdminPage.visiting do |page|
34
+ page.verify_status_code_is 200
35
+ end
39
36
  end
40
37
 
41
38
  it 'renders the feature flag name, default and description' do
42
- visit '/'
43
-
44
- on_flag_section.should_not be_nil
45
- on_flag_section.find('h3').text.should == 'on_by_default'
46
- on_flag_section.find('p').text.should == 'this flag on by default'
47
- on_flag_section.find('label.default').text.should include('Default (On)')
48
-
49
- off_flag_section.should_not be_nil
50
- off_flag_section.find('h3').text.should == 'off_by_default'
51
- off_flag_section.find('p').text.should == 'this flag off by default'
52
- off_flag_section.find('label.default').text.should include('Default (Off)')
39
+ AdminPage.visiting do |page|
40
+ on_flag_section = page.section_for_flag_named('on_by_default')
41
+ on_flag_section.should_not be_nil
42
+ on_flag_section.find('h3').text.should == 'on_by_default'
43
+ on_flag_section.find('p').text.should == 'this flag on by default'
44
+ on_flag_section.find('label.default').text.should include('Default (On)')
45
+
46
+ off_flag_section = page.section_for_flag_named('off_by_default')
47
+ off_flag_section.should_not be_nil
48
+ off_flag_section.find('h3').text.should == 'off_by_default'
49
+ off_flag_section.find('p').text.should == 'this flag off by default'
50
+ off_flag_section.find('label.default').text.should include('Default (Off)')
51
+ end
53
52
  end
54
53
 
55
54
  it 'selects the default option if there are no cookies present' do
56
- visit '/'
57
-
58
- verify_flag_section( on_flag_section, :default )
59
- verify_flag_section( off_flag_section, :default )
55
+ AdminPage.visiting do |page|
56
+ page.verify_flag_section( 'on_by_default', :default )
57
+ page.verify_flag_section( 'off_by_default', :default )
58
+ end
60
59
  end
61
60
 
62
61
  it 'allows switching off a flag defaulted to on' do
63
- visit '/'
64
-
65
- on_flag_section.choose( 'Off' )
66
- update_button.click
67
-
68
- verify_flag_section( on_flag_section, :off )
69
- verify_flag_section( off_flag_section, :default )
70
- end
71
-
72
- def verify_flag_section( section, expected_state )
73
- case expected_state.to_sym
74
- when :default
75
- section.find('label.default input').should be_checked
76
-
77
- section.find('label.on input').should_not be_checked
78
- section.find('label.off input').should_not be_checked
79
- when :on
80
- section.find('label.on input').should be_checked
81
-
82
- section.find('label.default input').should_not be_checked
83
- section.find('label.off input').should_not be_checked
84
- when :off
85
- section.find('label.off input').should be_checked
62
+ AdminPage.visiting do |page|
63
+ page.turn_off_flag_name('on_by_default')
86
64
 
87
- section.find('label.default input').should_not be_checked
88
- section.find('label.on input').should_not be_checked
89
- else
90
- raise "unrecognized state '#{expected_state}'"
65
+ page.verify_flag_section( 'on_by_default', :off )
66
+ page.verify_flag_section( 'off_by_default', :default )
91
67
  end
92
68
  end
93
69
  end
@@ -0,0 +1,44 @@
1
+ require_relative 'spec_helper'
2
+ require_relative 'support/page_objects/admin_page'
3
+ require_relative 'support/page_objects/reader_page'
4
+
5
+ describe 'end-to-end flow of setting a feature flag in the admin app and seeing its effect' do
6
+
7
+ let( :app ) do
8
+ yaml_path = ff_config_file_path
9
+ Rack::Builder.new do
10
+ use RackFlags::RackMiddleware, yaml_path: yaml_path
11
+ map('/reader'){ run ReaderApp }
12
+ map('/feature_flags'){ run RackFlags::AdminApp.new }
13
+ end
14
+ end
15
+
16
+ let( :feature_flag_config ) do
17
+ {
18
+ foo: { default: true },
19
+ bar: { default: false }
20
+ }
21
+ end
22
+
23
+ before :each do
24
+ ff_config_file_contains( feature_flag_config )
25
+ Capybara.app = app
26
+ end
27
+
28
+ it 'overriding an off flag to on' do
29
+ ReaderPage.visiting('/reader') do |page|
30
+ page.verify_flag_is_on('foo')
31
+ page.verify_flag_is_off('bar')
32
+ end
33
+
34
+ AdminPage.visiting('/feature_flags') do |page|
35
+ page.turn_on_flag_name('bar')
36
+ end
37
+
38
+ ReaderPage.visiting('/reader') do |page|
39
+ page.verify_flag_is_on('foo')
40
+ page.verify_flag_is_on('bar')
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,66 @@
1
+ class AdminPage
2
+ include RSpec::Matchers
3
+ include Capybara::DSL
4
+
5
+ def self.visiting( path = "/" )
6
+ page = self.new(path)
7
+ page.visit_page
8
+ yield page
9
+ end
10
+
11
+ def initialize( path )
12
+ @path = path
13
+ end
14
+
15
+ def visit_page
16
+ visit @path
17
+ end
18
+
19
+ def turn_on_flag_name(flag_name)
20
+ section_for_flag_named(flag_name).choose('On')
21
+ update_button.click
22
+ end
23
+
24
+ def turn_off_flag_name(flag_name)
25
+ section_for_flag_named(flag_name).choose('Off')
26
+ update_button.click
27
+ end
28
+
29
+
30
+ def update_button
31
+ page.find('input[type="submit"]')
32
+ end
33
+
34
+ def section_for_flag_named(flag_name)
35
+ page.find(%Q|section[data-flag-name="#{flag_name}"]|)
36
+ end
37
+
38
+ def verify_flag_section( flag_name, expected_state )
39
+ section = section_for_flag_named( flag_name )
40
+
41
+ case expected_state.to_sym
42
+ when :default
43
+ section.find('label.default input').should be_checked
44
+
45
+ section.find('label.on input').should_not be_checked
46
+ section.find('label.off input').should_not be_checked
47
+ when :on
48
+ section.find('label.on input').should be_checked
49
+
50
+ section.find('label.default input').should_not be_checked
51
+ section.find('label.off input').should_not be_checked
52
+ when :off
53
+ section.find('label.off input').should be_checked
54
+
55
+ section.find('label.default input').should_not be_checked
56
+ section.find('label.on input').should_not be_checked
57
+ else
58
+ raise "unrecognized state '#{expected_state}'"
59
+ end
60
+ end
61
+
62
+ def verify_status_code_is(expected_status_code)
63
+ status_code.should == expected_status_code
64
+ end
65
+
66
+ end
@@ -0,0 +1,27 @@
1
+ class ReaderPage
2
+ include RSpec::Matchers
3
+ include Capybara::DSL
4
+
5
+ def self.visiting( path = "/" )
6
+ page = self.new(path)
7
+ page.visit_page
8
+ yield page
9
+ end
10
+
11
+ def initialize( path )
12
+ @path = path
13
+ end
14
+
15
+ def visit_page
16
+ visit(@path)
17
+ end
18
+
19
+ def verify_flag_is_off(flag_name)
20
+ page.should have_content("#{flag_name} is off")
21
+ end
22
+
23
+ def verify_flag_is_on(flag_name)
24
+ page.should have_content("#{flag_name} is on")
25
+ end
26
+
27
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-flags
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-08-06 00:00:00.000000000 Z
13
+ date: 2013-08-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
17
- requirement: &70155779355400 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,15 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70155779355400
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
26
31
  - !ruby/object:Gem::Dependency
27
32
  name: rack
28
- requirement: &70155779354880 !ruby/object:Gem::Requirement
33
+ requirement: !ruby/object:Gem::Requirement
29
34
  none: false
30
35
  requirements:
31
36
  - - ~>
@@ -33,10 +38,15 @@ dependencies:
33
38
  version: '1.4'
34
39
  type: :runtime
35
40
  prerelease: false
36
- version_requirements: *70155779354880
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: '1.4'
37
47
  - !ruby/object:Gem::Dependency
38
48
  name: sinatra
39
- requirement: &70155779354360 !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
40
50
  none: false
41
51
  requirements:
42
52
  - - ~>
@@ -44,10 +54,15 @@ dependencies:
44
54
  version: '1.3'
45
55
  type: :runtime
46
56
  prerelease: false
47
- version_requirements: *70155779354360
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: '1.3'
48
63
  - !ruby/object:Gem::Dependency
49
64
  name: pry-debugger
50
- requirement: &70155779353980 !ruby/object:Gem::Requirement
65
+ requirement: !ruby/object:Gem::Requirement
51
66
  none: false
52
67
  requirements:
53
68
  - - ! '>='
@@ -55,10 +70,15 @@ dependencies:
55
70
  version: '0'
56
71
  type: :development
57
72
  prerelease: false
58
- version_requirements: *70155779353980
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
59
79
  - !ruby/object:Gem::Dependency
60
80
  name: rspec-core
61
- requirement: &70155779353520 !ruby/object:Gem::Requirement
81
+ requirement: !ruby/object:Gem::Requirement
62
82
  none: false
63
83
  requirements:
64
84
  - - ! '>='
@@ -66,10 +86,15 @@ dependencies:
66
86
  version: '0'
67
87
  type: :development
68
88
  prerelease: false
69
- version_requirements: *70155779353520
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
70
95
  - !ruby/object:Gem::Dependency
71
96
  name: rspec-expectations
72
- requirement: &70155779353100 !ruby/object:Gem::Requirement
97
+ requirement: !ruby/object:Gem::Requirement
73
98
  none: false
74
99
  requirements:
75
100
  - - ! '>='
@@ -77,10 +102,15 @@ dependencies:
77
102
  version: '0'
78
103
  type: :development
79
104
  prerelease: false
80
- version_requirements: *70155779353100
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
81
111
  - !ruby/object:Gem::Dependency
82
112
  name: rr
83
- requirement: &70155779352680 !ruby/object:Gem::Requirement
113
+ requirement: !ruby/object:Gem::Requirement
84
114
  none: false
85
115
  requirements:
86
116
  - - ! '>='
@@ -88,10 +118,15 @@ dependencies:
88
118
  version: '0'
89
119
  type: :development
90
120
  prerelease: false
91
- version_requirements: *70155779352680
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
92
127
  - !ruby/object:Gem::Dependency
93
128
  name: capybara
94
- requirement: &70155779352260 !ruby/object:Gem::Requirement
129
+ requirement: !ruby/object:Gem::Requirement
95
130
  none: false
96
131
  requirements:
97
132
  - - ! '>='
@@ -99,7 +134,12 @@ dependencies:
99
134
  version: '0'
100
135
  type: :development
101
136
  prerelease: false
102
- version_requirements: *70155779352260
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
103
143
  description: This is a simple lightweight way to expose work-in-progress functionality
104
144
  to developers, testers or other internal users.
105
145
  email:
@@ -118,8 +158,11 @@ files:
118
158
  - resources/admin_app/index.erb
119
159
  - resources/admin_app/style.css
120
160
  - spec/acceptance/administering_feature_flags_spec.rb
161
+ - spec/acceptance/end_to_end_flow_spec.rb
121
162
  - spec/acceptance/reading_feature_flags_spec.rb
122
163
  - spec/acceptance/spec_helper.rb
164
+ - spec/acceptance/support/page_objects/admin_page.rb
165
+ - spec/acceptance/support/page_objects/reader_page.rb
123
166
  - spec/acceptance/support/reader_app.rb
124
167
  - spec/spec_helper.rb
125
168
  - spec/unit/admin_app_spec.rb
@@ -141,22 +184,31 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
184
  - - ! '>='
142
185
  - !ruby/object:Gem::Version
143
186
  version: '0'
187
+ segments:
188
+ - 0
189
+ hash: -1587276137499646704
144
190
  required_rubygems_version: !ruby/object:Gem::Requirement
145
191
  none: false
146
192
  requirements:
147
193
  - - ! '>='
148
194
  - !ruby/object:Gem::Version
149
195
  version: '0'
196
+ segments:
197
+ - 0
198
+ hash: -1587276137499646704
150
199
  requirements: []
151
200
  rubyforge_project:
152
- rubygems_version: 1.8.15
201
+ rubygems_version: 1.8.25
153
202
  signing_key:
154
203
  specification_version: 3
155
204
  summary: Simple cookie-based feature flags using Rack.
156
205
  test_files:
157
206
  - spec/acceptance/administering_feature_flags_spec.rb
207
+ - spec/acceptance/end_to_end_flow_spec.rb
158
208
  - spec/acceptance/reading_feature_flags_spec.rb
159
209
  - spec/acceptance/spec_helper.rb
210
+ - spec/acceptance/support/page_objects/admin_page.rb
211
+ - spec/acceptance/support/page_objects/reader_page.rb
160
212
  - spec/acceptance/support/reader_app.rb
161
213
  - spec/spec_helper.rb
162
214
  - spec/unit/admin_app_spec.rb