site-inspector 2.0.0 → 3.0.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.
@@ -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)