browsernizer 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -37,17 +37,14 @@ It states that IE9+, FF4+, Opera 11.1+ and Chrome 7+ are supported.
37
37
  Non listed browsers are considered to be supported regardless of their version.
38
38
  Unsupported browsers will be redirected to `/browser.html` page.
39
39
 
40
- By default, only requests with `HTTP_ACCEPT` header set to `text/html` are
41
- processed. Sometimes this header is not set by the browser. To overcome this
42
- issue, the `exclude` option is added to the config.
43
-
44
40
  You can specify which paths you wish to exclude with `exclude` method.
45
41
  It accepts string or regular expression. You can specify multiple paths by
46
42
  calling the `config.exclude` multiple times.
47
43
 
48
44
  If you wish to completely prevent some browsers from accessing website
49
- (regardless of their version), for now you can specify some really high
50
- version number (e.g. "666").
45
+ (regardless of their version), just set browser version to `false`.
46
+
47
+ config.supported "Internet Explorer", false
51
48
 
52
49
  Specifying location is optional. If you prefer handling unsupported browsers on
53
50
  your own, you can access browsernizer info from `request.env['browsernizer']`
@@ -1,6 +1,30 @@
1
1
  module Browsernizer
2
2
 
3
- class Browser < Struct.new(:browser, :version)
3
+ class Browser
4
+
5
+ attr_reader :name, :version
6
+
7
+ def initialize(name, version)
8
+ @name = name.to_s
9
+ if version === false
10
+ @version = false
11
+ else
12
+ @version = BrowserVersion.new version.to_s
13
+ end
14
+ end
15
+
16
+ def meets?(requirement)
17
+ if name.downcase == requirement.name.downcase
18
+ if requirement.version === false
19
+ false
20
+ else
21
+ version >= requirement.version
22
+ end
23
+ else
24
+ nil
25
+ end
26
+ end
27
+
4
28
  end
5
29
 
6
30
  end
@@ -20,5 +20,9 @@ module Browsernizer
20
20
  0
21
21
  end
22
22
 
23
+ def to_s
24
+ @version
25
+ end
26
+
23
27
  end
24
28
  end
@@ -9,7 +9,7 @@ module Browsernizer
9
9
  end
10
10
 
11
11
  def supported(browser, version)
12
- @supported << Browser.new(browser.to_s, version.to_s)
12
+ @supported << Browser.new(browser, version)
13
13
  end
14
14
 
15
15
  def location(path)
@@ -39,9 +39,5 @@ module Browsernizer
39
39
  end
40
40
  end
41
41
 
42
- def exclusions_defined?
43
- @exclusions.length > 0
44
- end
45
-
46
42
  end
47
43
  end
@@ -13,7 +13,7 @@ module Browsernizer
13
13
  @env = env
14
14
  @env["browsernizer"] = {
15
15
  "supported" => true,
16
- "browser" => agent.browser.to_s,
16
+ "browser" => agent.name.to_s,
17
17
  "version" => agent.version.to_s
18
18
  }
19
19
  handle_request
@@ -21,13 +21,18 @@ module Browsernizer
21
21
 
22
22
  private
23
23
  def handle_request
24
- if !html_request? || path_excluded?
25
- propagate_request
26
- elsif !on_redirection_path? && unsupported?
27
- handle_unsupported
28
- elsif on_redirection_path? && !unsupported?
29
- handle_visits_by_accident
30
- else
24
+ @env["browsernizer"]["supported"] = false if unsupported?
25
+
26
+ catch(:response) do
27
+ if !path_excluded?
28
+ if unsupported?
29
+ if !on_redirection_path? && @config.get_location
30
+ throw :response, redirect_to_specified
31
+ end
32
+ elsif on_redirection_path?
33
+ throw :response, redirect_to_root
34
+ end
35
+ end
31
36
  propagate_request
32
37
  end
33
38
  end
@@ -36,48 +41,31 @@ module Browsernizer
36
41
  @app.call(@env)
37
42
  end
38
43
 
39
- def handle_unsupported
40
- @env["browsernizer"]["supported"] = false
41
-
42
- if @config.get_location
43
- [307, {"Content-Type" => "text/plain", "Location" => @config.get_location}, []]
44
- else
45
- propagate_request
46
- end
44
+ def redirect_to_specified
45
+ [307, {"Content-Type" => "text/plain", "Location" => @config.get_location}, []]
47
46
  end
48
47
 
49
- def handle_visits_by_accident
48
+ def redirect_to_root
50
49
  [303, {"Content-Type" => "text/plain", "Location" => "/"}, []]
51
50
  end
52
51
 
53
- # if exclusions are defined, we'll be ignoring HTTP_ACCEPT header
54
- def html_request?
55
- return true if @config.exclusions_defined?
56
- @env["HTTP_ACCEPT"] && @env["HTTP_ACCEPT"].include?("text/html")
57
- end
58
-
59
52
  def path_excluded?
60
53
  @config.excluded? @env["PATH_INFO"]
61
54
  end
62
55
 
63
56
  def on_redirection_path?
64
- @env["PATH_INFO"] && @env["PATH_INFO"] == @config.get_location
57
+ @config.get_location && @config.get_location == @env["PATH_INFO"]
65
58
  end
66
59
 
67
60
  def agent
68
- ::UserAgent.parse @env["HTTP_USER_AGENT"]
61
+ a = ::UserAgent.parse @env["HTTP_USER_AGENT"]
62
+ Browser.new a.browser.to_s, a.version.to_s
69
63
  end
70
64
 
71
65
  # supported by default
72
66
  def unsupported?
73
- @config.get_supported.detect do |supported_browser|
74
- if agent.browser.to_s.downcase == supported_browser.browser.to_s.downcase
75
- a = BrowserVersion.new agent.version.to_s
76
- b = BrowserVersion.new supported_browser.version.to_s
77
- a < b
78
- end
79
- # TODO: when useragent is fixed you can use just this line instead the above
80
- # agent < supported_browser
67
+ @config.get_supported.any? do |requirement|
68
+ agent.meets?(requirement) === false
81
69
  end
82
70
  end
83
71
  end
@@ -1,3 +1,3 @@
1
1
  module Browsernizer
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Browsernizer::Browser do
4
+
5
+ describe "#meets?(requirement)" do
6
+ context "same vendor" do
7
+ it "returns true if version is >= to requirement" do
8
+ browser("Chrome", "10.0").meets?(browser("Chrome", "10" )).should be_true
9
+ browser("Chrome", "10.0").meets?(browser("Chrome", "10.1")).should be_false
10
+ browser("Chrome", "10" ).meets?(browser("Chrome", " 9.1")).should be_true
11
+ end
12
+ it "returns false if requirement version is set to false" do
13
+ browser("Chrome", "10" ).meets?(browser("Chrome", false )).should be_false
14
+ end
15
+ end
16
+
17
+ context "different vendors" do
18
+ it "returns nil" do
19
+ browser("Chrome", "10").meets?(browser("Firefox", "10")).should be_nil
20
+ end
21
+ end
22
+ end
23
+
24
+ def browser(name, version)
25
+ Browsernizer::Browser.new(name, version)
26
+ end
27
+
28
+ end
@@ -10,6 +10,11 @@ describe Browsernizer::Config do
10
10
  subject.supported "Firefox", "10.0"
11
11
  subject.get_supported.should have(2).items
12
12
  end
13
+
14
+ it "allows to unsupport browser by using false as version number" do
15
+ subject.supported "Chrome", false
16
+ subject.get_supported[0].version.should be_false
17
+ end
13
18
  end
14
19
 
15
20
  describe "location(path)" do
@@ -29,8 +34,6 @@ describe Browsernizer::Config do
29
34
  subject.excluded?("/prefix/assets/foo.jpg").should be_false
30
35
  subject.excluded?("/foo/bar.html").should be_true
31
36
  subject.excluded?("/foo/bar2.html").should be_false
32
-
33
- subject.exclusions_defined?.should be_true
34
37
  end
35
38
  end
36
39
 
@@ -6,7 +6,7 @@ describe Browsernizer::Router do
6
6
 
7
7
  subject do
8
8
  Browsernizer::Router.new(app) do |config|
9
- config.supported "Firefox", "4"
9
+ config.supported "Firefox", false
10
10
  config.supported "Chrome", "7.1"
11
11
  end
12
12
  end
@@ -14,50 +14,42 @@ describe Browsernizer::Router do
14
14
  let(:default_env) do
15
15
  {
16
16
  "HTTP_USER_AGENT" => chrome_agent("7.1.1"),
17
- "HTTP_ACCEPT" => "text/html",
18
17
  "PATH_INFO" => "/index"
19
18
  }
20
19
  end
21
20
 
22
21
  context "All Good" do
23
- it "sets browsernizer env and propagates request" do
24
- response = default_env.dup
25
- response['browsernizer'] = {
26
- 'supported' => true,
27
- 'browser' => "Chrome",
28
- 'version' => "7.1.1"
29
- }
30
- app.should_receive(:call).with(response)
22
+ it "propagates requrest with updated env" do
23
+ app.should_receive(:call).with do |env|
24
+ env['browsernizer']['supported'].should be_true
25
+ env['browsernizer']['browser'].should == "Chrome"
26
+ env['browsernizer']['version'].should == "7.1.1"
27
+ end
31
28
  subject.call(default_env)
32
29
  end
33
30
  end
34
31
 
35
- context "Unsupported Browser" do
36
- before do
37
- @env = default_env.merge({
38
- "HTTP_USER_AGENT" => chrome_agent("7")
39
- })
40
- end
41
32
 
42
- it "updates 'browsernizer' env variable and propagates request" do
43
- @response = @env.dup
44
- @response['browsernizer'] = {
45
- 'supported' => false,
46
- 'browser' => "Chrome",
47
- 'version' => "7"
48
- }
49
- app.should_receive(:call).with(@response)
50
- subject.call(@env)
33
+ shared_examples "unsupported browser" do
34
+ context "location not set" do
35
+ it "propagates requrest with updated env" do
36
+ app.should_receive(:call).with do |env|
37
+ env['browsernizer']['supported'].should be_false
38
+ end
39
+ subject.call(@env)
40
+ end
51
41
  end
52
42
 
53
43
  context "location is set" do
54
44
  before do
55
45
  subject.config.location "/browser.html"
56
46
  end
47
+
57
48
  it "prevents propagation" do
58
49
  app.should_not_receive(:call)
59
50
  subject.call(@env)
60
51
  end
52
+
61
53
  it "redirects to proper location" do
62
54
  response = subject.call(@env)
63
55
  response[0].should == 307
@@ -76,50 +68,47 @@ describe Browsernizer::Router do
76
68
  subject.call(@env)
77
69
  end
78
70
  end
79
- end
80
71
 
81
- context "Non-html request" do
82
- before do
83
- @env = @env.merge({
84
- "HTTP_ACCEPT" => "text/css"
85
- })
86
- end
87
- it "propagates request" do
88
- app.should_receive(:call).with(@env)
89
- subject.call(@env)
90
- end
91
-
92
- context "exclusions defined" do
72
+ context "Already on /browser.html page" do
93
73
  before do
94
- subject.config.exclude %r{^/assets}
95
- subject.config.location "/browser.html"
74
+ @env = @env.merge({
75
+ "PATH_INFO" => "/browser.html"
76
+ })
96
77
  end
97
- it "handles the request" do
98
- app.should_not_receive(:call).with(@env)
99
- response = subject.call(@env)
100
- response[0].should == 307
101
- response[1]["Location"].should == "/browser.html"
78
+ it "propagates requrest with updated env" do
79
+ app.should_receive(:call).with do |env|
80
+ env['browsernizer']['supported'].should be_false
81
+ end
82
+ subject.call(@env)
102
83
  end
103
84
  end
104
85
  end
86
+ end
105
87
 
106
-
107
- context "Already on /browser.html page" do
108
- before do
109
- @env = @env.merge({
110
- "PATH_INFO" => "/browser.html"
111
- })
112
- end
113
- it "propagates request" do
114
- app.should_receive(:call).with(@env)
115
- subject.call(@env)
116
- end
88
+ context "Unsupported Version" do
89
+ before do
90
+ @env = default_env.merge({
91
+ "HTTP_USER_AGENT" => chrome_agent("7")
92
+ })
117
93
  end
94
+ it_behaves_like "unsupported browser"
118
95
  end
119
96
 
97
+ context "Unsupported Vendor" do
98
+ before do
99
+ @env = default_env.merge({
100
+ "HTTP_USER_AGENT" => firefox_agent("10.0.1")
101
+ })
102
+ end
103
+ it_behaves_like "unsupported browser"
104
+ end
120
105
 
121
106
  def chrome_agent(version)
122
107
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/#{version} Safari/535.7"
123
108
  end
124
109
 
110
+ def firefox_agent(version)
111
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.1) Gecko/20100101 Firefox/#{version}"
112
+ end
113
+
125
114
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browsernizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-14 00:00:00.000000000Z
12
+ date: 2012-02-15 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70284088116900 !ruby/object:Gem::Requirement
16
+ requirement: &70146036473060 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70284088116900
24
+ version_requirements: *70146036473060
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70284088116480 !ruby/object:Gem::Requirement
27
+ requirement: &70146036472640 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70284088116480
35
+ version_requirements: *70146036472640
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: useragent
38
- requirement: &70284088115980 !ruby/object:Gem::Requirement
38
+ requirement: &70146036472140 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: 0.4.6
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70284088115980
46
+ version_requirements: *70146036472140
47
47
  description: Rack middleware for redirecting unsupported user agents to "please upgrade"
48
48
  page
49
49
  email:
@@ -65,6 +65,7 @@ files:
65
65
  - lib/browsernizer/version.rb
66
66
  - lib/generators/browsernizer/install_generator.rb
67
67
  - lib/generators/templates/browsernizer.rb
68
+ - spec/browsernizer/browser_spec.rb
68
69
  - spec/browsernizer/browser_version_spec.rb
69
70
  - spec/browsernizer/config_spec.rb
70
71
  - spec/browsernizer/router_spec.rb
@@ -94,6 +95,7 @@ signing_key:
94
95
  specification_version: 3
95
96
  summary: Want friendly "please upgrade your browser" page? This gem is for you.
96
97
  test_files:
98
+ - spec/browsernizer/browser_spec.rb
97
99
  - spec/browsernizer/browser_version_spec.rb
98
100
  - spec/browsernizer/config_spec.rb
99
101
  - spec/browsernizer/router_spec.rb