site-inspector 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe SiteInspector::Endpoint::Accessibility do
4
+
5
+ subject do
6
+ endpoint = SiteInspector::Endpoint.new("http://example.com")
7
+ SiteInspector::Endpoint::Accessibility.new(endpoint)
8
+ end
9
+
10
+ it "retrieve's pa11y's version" do
11
+ expect(subject.class.pa11y_version).to match(/\d\.\d\.\d/)
12
+ end
13
+
14
+ it "responds to valid standards" do
15
+ expect(subject.respond_to?(:section508)).to eql(true)
16
+ end
17
+
18
+ it "knows the level" do
19
+ expect(subject.level).to eql(:error)
20
+ end
21
+
22
+ it "allows the user to set the level" do
23
+ subject.level = :warning
24
+ expect(subject.level).to eql(:warning)
25
+ end
26
+
27
+ it "errors on invalid levels" do
28
+ expect{subject.level="foo"}.to raise_error(ArgumentError)
29
+ end
30
+
31
+ it "knows the standard" do
32
+ expect(subject.standard).to eql(:section508)
33
+ end
34
+
35
+ it "allows the user to set the standard" do
36
+ subject.standard = :wcag2a
37
+ expect(subject.standard).to eql(:wcag2a)
38
+ end
39
+
40
+ it "errors on invalid standards" do
41
+ expect{subject.standard=:foo}.to raise_error(ArgumentError)
42
+ end
43
+
44
+ context "with pa11y installed" do
45
+
46
+ before do
47
+ stub_request(:get, "http://example.com/").to_return(:status => 200 )
48
+ end
49
+
50
+ end
51
+
52
+ context "with pa11y stub'd" do
53
+
54
+ before do
55
+ output = '[{"code":"Section508.L.NoContentAnchor","context":"<a href=\"foo\"></a>","message":"Anchor element found with a valid href attribute, but no link content has been supplied.","selector":"html > body > a","type":"error","typeCode":1}]'
56
+ allow(subject).to receive(:run_command) { [output, 2] }
57
+ end
58
+
59
+ it "knows if pa11y is installed" do
60
+ expect(subject.class.pa11y?).to eql(true)
61
+ end
62
+
63
+ it "knows if a site is valid" do
64
+ expect(subject.valid?).to eql(false)
65
+ end
66
+
67
+ it "counts the errors" do
68
+ expect(subject.errors).to eql(1)
69
+ end
70
+
71
+ it "runs the check" do
72
+ expect(subject.check[:valid]).to eql(false)
73
+ expect(subject.check[:results].first["code"]).to eql("Section508.L.NoContentAnchor")
74
+ end
75
+
76
+ it "runs a named check" do
77
+ expect(subject.check[:valid]).to eql(false)
78
+ expect(subject.check[:results].first["code"]).to eql("Section508.L.NoContentAnchor")
79
+ end
80
+ end
81
+ end
@@ -31,4 +31,8 @@ describe SiteInspector::Endpoint::Check do
31
31
  it "returns the instance name" do
32
32
  expect(SiteInspector::Endpoint::Check.name).to eql(:check)
33
33
  end
34
+
35
+ it "enables the check" do
36
+ expect(SiteInspector::Endpoint::Check.enabled?).to eql(true)
37
+ end
34
38
  end
@@ -4,7 +4,7 @@ describe SiteInspector::Endpoint::Content do
4
4
 
5
5
  subject do
6
6
  body = <<-eos
7
- <!DOCTYPE html>
7
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
8
8
  <html>
9
9
  <body>
10
10
  <h1>Some page</h1>
@@ -28,40 +28,52 @@ describe SiteInspector::Endpoint::Content do
28
28
  end
29
29
 
30
30
  it "returns the doctype" do
31
- expect(subject.doctype).to eql("html")
31
+ expect(subject.doctype).to eql("-//W3C//DTD XHTML 1.0 Transitional//EN")
32
32
  end
33
33
 
34
34
  it "knows when robots.txt exists" do
35
+ stub_request(:get, /http\:\/\/example.com\/[a-z0-9]{32}/i).to_return(:status => 404)
36
+
35
37
  stub_request(:get, "http://example.com/robots.txt").
36
38
  to_return(:status => 200)
37
39
  expect(subject.robots_txt?).to eql(true)
38
40
  end
39
41
 
40
42
  it "knows when robots.txt doesn't exist" do
43
+ stub_request(:get, /http\:\/\/example.com\/[a-z0-9]{32}/i).to_return(:status => 404)
44
+
41
45
  stub_request(:get, "http://example.com/robots.txt").
42
46
  to_return(:status => 404)
43
47
  expect(subject.robots_txt?).to eql(false)
44
48
  end
45
49
 
46
50
  it "knows when sitemap.xml exists" do
51
+ stub_request(:get, /http\:\/\/example.com\/[a-z0-9]{32}/i).to_return(:status => 404)
52
+
47
53
  stub_request(:get, "http://example.com/sitemap.xml").
48
54
  to_return(:status => 200)
49
55
  expect(subject.sitemap_xml?).to eql(true)
50
56
  end
51
57
 
52
58
  it "knows when sitemap.xml exists" do
59
+ stub_request(:get, /http\:\/\/example.com\/[a-z0-9]{32}/i).to_return(:status => 404)
60
+
53
61
  stub_request(:get, "http://example.com/sitemap.xml").
54
62
  to_return(:status => 404)
55
63
  expect(subject.sitemap_xml?).to eql(false)
56
64
  end
57
65
 
58
66
  it "knows when humans.txt exists" do
67
+ stub_request(:get, /http\:\/\/example.com\/[a-z0-9]{32}/i).to_return(:status => 404)
68
+
59
69
  stub_request(:get, "http://example.com/humans.txt").
60
70
  to_return(:status => 200)
61
71
  expect(subject.humans_txt?).to eql(true)
62
72
  end
63
73
 
64
74
  it "knows when humans.txt doesn't exist" do
75
+ stub_request(:get, /http\:\/\/example.com\/[a-z0-9]{32}/i).to_return(:status => 404)
76
+
65
77
  stub_request(:get, "http://example.com/humans.txt").
66
78
  to_return(:status => 200)
67
79
  expect(subject.humans_txt?).to eql(true)
@@ -85,5 +97,11 @@ describe SiteInspector::Endpoint::Content do
85
97
  expect(path).to match /[a-z0-9]{32}/i
86
98
  expect(subject.send(:random_path)).to eql(path)
87
99
  end
100
+
101
+ it "doesn't say something exists when there are no 404s" do
102
+ stub_request(:get, /http\:\/\/example.com\/[a-z0-9]{32}/i).to_return(:status => 200)
103
+ stub_request(:get, "http://example.com/humans.txt").to_return(:status => 200)
104
+ expect(subject.humans_txt?).to eql(nil)
105
+ end
88
106
  end
89
107
  end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe SiteInspector::Endpoint::Cookies do
4
+
5
+ context "without cookies" do
6
+ subject do
7
+ stub_request(:get, "http://example.com/").
8
+ to_return(:status => 200, :body => "" )
9
+ endpoint = SiteInspector::Endpoint.new("http://example.com")
10
+ SiteInspector::Endpoint::Cookies.new(endpoint)
11
+ end
12
+
13
+ it "knows when there are no cookies" do
14
+ expect(subject.cookies?).to eql(false)
15
+ expect(subject.all).to eql(nil)
16
+ end
17
+ end
18
+
19
+ context "with cookies" do
20
+ subject do
21
+ cookies = [
22
+ CGI::Cookie::new(
23
+ "name" => "foo",
24
+ "value" => "bar",
25
+ "domain" => "example.com",
26
+ "path" => "/"
27
+ ),
28
+ CGI::Cookie::new(
29
+ "name" => "foo2",
30
+ "value" => "bar2",
31
+ "domain" => "example.com",
32
+ "path" => "/"
33
+ )
34
+ ].map { |c| c.to_s }
35
+
36
+ stub_request(:get, "http://example.com/").
37
+ to_return(:status => 200, :body => "", :headers => { "set-cookie" => cookies })
38
+ endpoint = SiteInspector::Endpoint.new("http://example.com")
39
+ SiteInspector::Endpoint::Cookies.new(endpoint)
40
+ end
41
+
42
+ it "knows when there are cookies" do
43
+ expect(subject.cookies?).to eql(true)
44
+ expect(subject.all.count).to eql(2)
45
+ end
46
+
47
+ it "returns a cookie by name" do
48
+ expect(subject["foo"].to_s).to match(/foo=bar/)
49
+ end
50
+
51
+ it "knows cookies aren't secure" do
52
+ expect(subject.secure?).to eql(false)
53
+ end
54
+ end
55
+
56
+ context "with secure cookies" do
57
+ subject do
58
+ cookies = [
59
+ "foo=bar; domain=example.com; path=/; secure; HttpOnly",
60
+ "foo2=bar2; domain=example.com; path=/"
61
+ ]
62
+ stub_request(:get, "http://example.com/").
63
+ to_return(:status => 200, :body => "", :headers => { "set-cookie" => cookies })
64
+ endpoint = SiteInspector::Endpoint.new("http://example.com")
65
+ SiteInspector::Endpoint::Cookies.new(endpoint)
66
+ end
67
+
68
+ it "knows cookies are secure" do
69
+ expect(subject.secure?).to eql(true)
70
+ end
71
+ end
72
+ end
@@ -61,14 +61,4 @@ describe SiteInspector::Endpoint::Headers do
61
61
  expect(subject.strict_transport_security).to eql("foo")
62
62
  expect(subject.strict_transport_security?).to eql(true)
63
63
  end
64
-
65
- it "knows if there are cookies" do
66
- expect(subject.cookies?).to eql(false)
67
- stub_header "set-cookie", "foo"
68
- expect(subject.cookies?).to eql(true)
69
- end
70
-
71
- it "knows if the cookies are secure" do
72
-
73
- end
74
64
  end
@@ -2,51 +2,113 @@ require 'spec_helper'
2
2
 
3
3
  describe SiteInspector::Endpoint::Sniffer do
4
4
 
5
- subject do
6
- body = <<-eos
7
- <html>
8
- <head>
9
- <link rel='stylesheet' href='/wp-content/themes/foo/style.css type='text/css' media='all' />
10
- </head>
11
- <body>
12
- <h1>Some page</h1>
13
- <script>
14
- jQuery(); googletag.pubads();
15
- </script>
16
- <script>
17
- var _gaq=[['_setAccount','UA-12345678-1'],['_trackPageview']];
18
- (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
19
- g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
20
- s.parentNode.insertBefore(g,s)}(document,'script'));
21
- </script>
22
- </body>
23
- </html>
24
- eos
5
+ def stub_header(header, value)
6
+ allow(subject.endpoint.headers).to receive(:headers) { { header => value } }
7
+ end
8
+
9
+ def set_cookie(key, value)
10
+ cookies = [
11
+ CGI::Cookie::new(
12
+ "name" => "foo",
13
+ "value" => "bar",
14
+ "domain" => "example.com",
15
+ "path" => "/"
16
+ ),
17
+ CGI::Cookie::new(
18
+ "name" => key,
19
+ "value" => value,
20
+ "domain" => "example.com",
21
+ "path" => "/"
22
+ )
23
+ ].map { |c| c.to_s }
25
24
 
26
25
  stub_request(:get, "http://example.com/").
27
- to_return(:status => 200, :body => body )
28
- endpoint = SiteInspector::Endpoint.new("http://example.com")
29
- SiteInspector::Endpoint::Sniffer.new(endpoint)
26
+ to_return(:status => 200, :body => "", :headers => { "set-cookie" => cookies } )
30
27
  end
31
28
 
32
- it "sniffs" do
33
- sniff = subject.send(:sniff, :cms)
34
- expect(sniff.keys.first).to eql(:wordpress)
35
- end
29
+ context "stubbed body" do
30
+ subject do
31
+ body = <<-eos
32
+ <html>
33
+ <head>
34
+ <link rel='stylesheet' href='/wp-content/themes/foo/style.css type='text/css' media='all' />
35
+ </head>
36
+ <body>
37
+ <h1>Some page</h1>
38
+ <script>
39
+ jQuery(); googletag.pubads();
40
+ </script>
41
+ <script>
42
+ var _gaq=[['_setAccount','UA-12345678-1'],['_trackPageview']];
43
+ (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
44
+ g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
45
+ s.parentNode.insertBefore(g,s)}(document,'script'));
46
+ </script>
47
+ </body>
48
+ </html>
49
+ eos
36
50
 
37
- it "detects the CMS" do
38
- expect(subject.cms.keys.first).to eql(:wordpress)
39
- end
51
+ stub_request(:get, "http://example.com/").
52
+ to_return(:status => 200, :body => body )
53
+ endpoint = SiteInspector::Endpoint.new("http://example.com")
54
+ SiteInspector::Endpoint::Sniffer.new(endpoint)
55
+ end
40
56
 
41
- it "detects the analytics" do
42
- expect(subject.analytics.keys.first).to eql(:google_analytics)
43
- end
57
+ it "sniffs" do
58
+ sniff = subject.send(:sniff, :cms)
59
+ expect(sniff).to eql(:wordpress)
60
+ end
61
+
62
+ it "detects the CMS" do
63
+ expect(subject.framework).to eql(:wordpress)
64
+ end
65
+
66
+ it "detects the analytics" do
67
+ expect(subject.analytics).to eql(:google_analytics)
68
+ end
44
69
 
45
- it "detects javascript" do
46
- expect(subject.javascript.keys.first).to eql(:jquery)
70
+ it "detects javascript" do
71
+ expect(subject.javascript).to eql(:jquery)
72
+ end
73
+
74
+ it "detects advertising" do
75
+ expect(subject.advertising).to eql(:adsense)
76
+ end
77
+
78
+ it "knows wordpress is open source" do
79
+ expect(subject.open_source?).to eql(true)
80
+ end
47
81
  end
48
82
 
49
- it "detects advertising" do
50
- expect(subject.advertising.keys.first).to eql(:adsense)
83
+ context "no body" do
84
+ subject do
85
+ endpoint = SiteInspector::Endpoint.new("http://example.com")
86
+ SiteInspector::Endpoint::Sniffer.new(endpoint)
87
+ end
88
+
89
+ it "knows when something isn't open source" do
90
+ set_cookie("foo", "bar")
91
+ expect(subject.open_source?).to eql(false)
92
+ end
93
+
94
+ it "detects PHP" do
95
+ set_cookie("PHPSESSID", "1234")
96
+ expect(subject.framework).to eql(:php)
97
+ expect(subject.open_source?).to eql(true)
98
+ end
99
+
100
+ it "detects Expression Engine" do
101
+ set_cookie("exp_csrf_token", "1234")
102
+ expect(subject.framework).to eql(:expression_engine)
103
+ expect(subject.open_source?).to eql(true)
104
+ end
105
+
106
+ it "detects cowboy" do
107
+ stub_request(:get, "http://example.com/").
108
+ to_return(:status => 200, :body => "", :headers => { "server" => "Cowboy" } )
109
+
110
+ expect(subject.framework).to eql(:cowboy)
111
+ expect(subject.open_source?).to eql(true)
112
+ end
51
113
  end
52
114
  end
@@ -2,30 +2,36 @@ require 'spec_helper'
2
2
 
3
3
  describe SiteInspector::DiskCache do
4
4
  subject { SiteInspector::DiskCache.new(tmpdir) }
5
-
5
+
6
6
  before do
7
7
  FileUtils.rm_rf(tmpdir)
8
8
  Dir.mkdir(tmpdir)
9
9
  end
10
10
 
11
11
  it "should write a value to disk" do
12
- path = File.expand_path "foo", tmpdir
12
+ foo = Typhoeus::Request.new("foo")
13
+
14
+ path = File.expand_path foo.cache_key, tmpdir
13
15
  expect(File.exists?(path)).to eql(false)
14
16
 
15
- subject.set "foo", "bar"
17
+ subject.set foo, "bar"
16
18
 
17
19
  expect(File.exists?(path)).to eql(true)
18
20
  expect(File.open(path).read).to eql("I\"bar:ET")
19
21
  end
20
22
 
21
23
  it "should read a value from disk" do
22
- path = File.expand_path "foo", tmpdir
24
+ foo = Typhoeus::Request.new("foo")
25
+
26
+ path = File.expand_path foo.cache_key, tmpdir
23
27
  File.write(path, "I\"bar:ET")
24
- expect(subject.get("foo")).to eql("bar")
28
+ expect(subject.get(foo)).to eql("bar")
25
29
  end
26
30
 
27
31
  it "should calculate a file's path" do
28
- path = File.expand_path "foo", tmpdir
29
- expect(subject.send(:path, "foo")).to eql(path)
32
+ foo = Typhoeus::Request.new("foo")
33
+
34
+ path = File.expand_path foo.cache_key, tmpdir
35
+ expect(subject.send(:path, foo)).to eql(path)
30
36
  end
31
37
  end
@@ -68,7 +68,29 @@ describe SiteInspector::Domain do
68
68
  end
69
69
 
70
70
  context "up" do
71
- it "considers an domain up if at least one endpoint is up" do
71
+ it "considers a domain up if at least one endpoint is up" do
72
+ subject.endpoints.each do |endpoint|
73
+ unless endpoint.uri.to_s.start_with?("http://www")
74
+ allow(endpoint).to receive(:response) { Typhoeus::Response.new(code: 0) }
75
+ end
76
+ end
77
+
78
+ stub_request(:get, "http://www.example.com/").to_return(:status => 200)
79
+
80
+ expect(subject.up?).to eql(true)
81
+ end
82
+
83
+ it "doesn't consider a domain up when all endpoints are down" do
84
+ subject.endpoints.each do |endpoint|
85
+ allow(endpoint).to receive(:response) { Typhoeus::Response.new(code: 0) }
86
+ end
87
+
88
+ expect(subject.up?).to eql(false)
89
+ end
90
+ end
91
+
92
+ context "up" do
93
+ it "considers a domain up if at least one endpoint is up" do
72
94
  stub_request(:get, "https://example.com/").to_return(:status => 500)
73
95
  stub_request(:get, "https://www.example.com/").to_return(:status => 500)
74
96
  stub_request(:get, "http://example.com/").to_return(:status => 500)
@@ -77,7 +99,7 @@ describe SiteInspector::Domain do
77
99
  expect(subject.up?).to eql(true)
78
100
  end
79
101
 
80
- it "doesn't consider an endpoint up when all endpoints are down" do
102
+ it "doesn't consider a domain up if all endpoints are down" do
81
103
  stub_request(:get, "https://example.com/").to_return(:status => 500)
82
104
  stub_request(:get, "https://www.example.com/").to_return(:status => 500)
83
105
  stub_request(:get, "http://example.com/").to_return(:status => 500)
@@ -94,7 +116,7 @@ describe SiteInspector::Domain do
94
116
  stub_request(:get, "http://example.com/").to_return(:status => 500)
95
117
  stub_request(:get, "http://www.example.com/").to_return(:status => 200)
96
118
 
97
- expect(subject.up?).to eql(true)
119
+ expect(subject.www?).to eql(true)
98
120
  end
99
121
 
100
122
  it "doesn't consider a site www when no endpoint is www" do
@@ -103,7 +125,7 @@ describe SiteInspector::Domain do
103
125
  stub_request(:get, "http://example.com/").to_return(:status => 200)
104
126
  stub_request(:get, "http://www.example.com/").to_return(:status => 500)
105
127
 
106
- expect(subject.up?).to eql(true)
128
+ expect(subject.www?).to eql(false)
107
129
  end
108
130
  end
109
131
 
@@ -166,11 +188,11 @@ describe SiteInspector::Domain do
166
188
  end
167
189
 
168
190
  it "detects when a domain downgrades to http" do
169
-
191
+ # TODO
170
192
  end
171
193
 
172
194
  it "detects when a domain enforces https" do
173
-
195
+ # TODO
174
196
  end
175
197
  end
176
198
 
@@ -96,15 +96,15 @@ describe SiteInspector::Endpoint do
96
96
  stub_request(:get, "http://example.com/").
97
97
  to_return(:status => 200, :body => "content")
98
98
 
99
- expect(subject.response?).to eql(true)
99
+ expect(subject.responds?).to eql(true)
100
100
  end
101
101
 
102
102
  it "knows when there's not a response" do
103
103
  allow(subject).to receive(:response) { Typhoeus::Response.new(code: 0) }
104
- expect(subject.response?).to eql(false)
104
+ expect(subject.responds?).to eql(false)
105
105
 
106
106
  allow(subject).to receive(:response) { Typhoeus::Response.new(:return_code => :operation_timedout) }
107
- expect(subject.response?).to eql(false)
107
+ expect(subject.responds?).to eql(false)
108
108
  end
109
109
 
110
110
  it "knows the response code" do
@@ -119,29 +119,50 @@ describe SiteInspector::Endpoint do
119
119
  expect(subject.timed_out?).to eql(true)
120
120
  end
121
121
 
122
- it "considers a 200 response code to be up" do
122
+ it "considers a 200 response code to be live and a response" do
123
123
  stub_request(:get, "http://example.com/").
124
124
  to_return(:status => 200)
125
125
 
126
126
  expect(subject.up?).to eql(true)
127
- expect(subject.down?).to eql(false)
128
-
127
+ expect(subject.responds?).to eql(true)
129
128
  end
130
129
 
131
- it "considers a 301 response code to be up" do
130
+ it "considers a 301 response code to be live and a response" do
132
131
  stub_request(:get, "http://example.com/").
133
132
  to_return(:status => 301)
134
133
 
135
134
  expect(subject.up?).to eql(true)
136
- expect(subject.down?).to eql(false)
135
+ expect(subject.responds?).to eql(true)
136
+ end
137
+
138
+ it "considers a 404 response code to be down but a response" do
139
+ stub_request(:get, "http://example.com/").
140
+ to_return(:status => 404)
141
+
142
+ expect(subject.up?).to eql(false)
143
+ expect(subject.responds?).to eql(true)
137
144
  end
138
145
 
139
- it "doesn't consider a 500 response code to be up" do
146
+ it "considers a 500 response code to be down but a response" do
140
147
  stub_request(:get, "http://example.com/").
141
148
  to_return(:status => 500)
142
149
 
143
150
  expect(subject.up?).to eql(false)
144
- expect(subject.down?).to eql(true)
151
+ expect(subject.responds?).to eql(true)
152
+ end
153
+
154
+ it "considers a 0 response code (error) to down and unresponsive" do
155
+ allow(subject).to receive(:response) { Typhoeus::Response.new(code: 0) }
156
+
157
+ expect(subject.up?).to eql(false)
158
+ expect(subject.responds?).to eql(false)
159
+ end
160
+
161
+ it "considers a timeout to be down and unresponsive" do
162
+ allow(subject).to receive(:response) { Typhoeus::Response.new(:return_code => :operation_timedout) }
163
+
164
+ expect(subject.up?).to eql(false)
165
+ expect(subject.responds?).to eql(false)
145
166
  end
146
167
  end
147
168
 
@@ -206,7 +227,7 @@ describe SiteInspector::Endpoint do
206
227
 
207
228
  context "checks" do
208
229
  it "identifies checks" do
209
- expect(SiteInspector::Endpoint.checks.count).to eql(6)
230
+ expect(SiteInspector::Endpoint.checks.count).to eql(8)
210
231
  end
211
232
 
212
233
  SiteInspector::Endpoint.checks.each do |check|
@@ -38,7 +38,7 @@ describe SiteInspector do
38
38
  :followlocation => false,
39
39
  :timeout => 10,
40
40
  :headers => {
41
- "User-Agent" => "Mozilla/5.0 (compatible; SiteInspector/#{SiteInspector::VERSION}; +https://github.com/benbalter/site-inspector-ruby)"
41
+ "User-Agent" => "Mozilla/5.0 (compatible; SiteInspector/#{SiteInspector::VERSION}; +https://github.com/benbalter/site-inspector)"
42
42
  }
43
43
  }
44
44
  expect(SiteInspector.typhoeus_defaults).to eql(expected)