rspec-webservice_matchers 4.0.0 → 4.0.1
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +0 -1
- data/README.md +0 -1
- data/Rakefile +1 -2
- data/lib/rspec/webservice_matchers/be_status.rb +20 -0
- data/lib/rspec/webservice_matchers/be_up.rb +20 -0
- data/lib/rspec/webservice_matchers/enforce_https_everywhere.rb +50 -0
- data/lib/rspec/webservice_matchers/have_a_valid_cert.rb +23 -0
- data/lib/rspec/webservice_matchers/redirect_permanently_to.rb +40 -0
- data/lib/rspec/webservice_matchers/redirect_temporarily_to.rb +41 -0
- data/lib/rspec/webservice_matchers/util.rb +83 -0
- data/lib/rspec/webservice_matchers/version.rb +1 -1
- data/lib/rspec/webservice_matchers.rb +6 -248
- data/rspec-webservice_matchers.gemspec +2 -1
- data/spec/rspec/webservice_matchers/protcol_spec.rb +2 -1
- data/spec/rspec/webservice_matchers/public_api_spec.rb +5 -4
- data/spec/rspec/webservice_matchers/ssl_spec.rb +6 -5
- metadata +13 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4356f7c49634e7a88471c05598307e27aaf5fbd
|
4
|
+
data.tar.gz: cdb55236a82a22067581d25ee24591470d658047
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c68cb9ac58edc93ae5cf0d16873a342e3d547ad32c35463fa0a315be5ac1d9d046d67ffede36e6dd4b46c254cea002504cb08ee16b8073192661e09d2fce550
|
7
|
+
data.tar.gz: df52ce370c307c92136d5da95cd3d361545d2b0674db8c19a7eca50e28d08e606becffc5a45da26d51de8d63f21c23302ff97679e529bee460b6dc87f5fe51e8
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/rspec-webservice_matchers) [](https://travis-ci.org/dogweather/rspec-webservice_matchers) [](https://codeclimate.com/github/dogweather/rspec-webservice_matchers)
|
4
4
|
|
5
|
-
[Issues and todo's are now managed Assembly as Bounties](https://assembly.com/think-200/bounties).
|
6
5
|
|
7
6
|
This [gem](https://rubygems.org/gems/rspec-webservice_matchers) enables you to black-box test a web app's server configuration. For example, whether its SSL certificate is correctly configured and not expired. It's a tool for doing **Test Driven Devops** (I just made that up). See [the introductory blog post](http://robb.weblaws.org/2014/01/16/new-open-source-library-for-test-driven-devops/) for more about the motivations for making this.
|
8
7
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rspec/webservice_matchers/util'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module WebserviceMatchers
|
5
|
+
# Pass when a URL returns the expected status code
|
6
|
+
# Codes are defined in http://www.rfc-editor.org/rfc/rfc2616.txt
|
7
|
+
RSpec::Matchers.define :be_status do |expected_code|
|
8
|
+
actual_code = nil
|
9
|
+
|
10
|
+
match do |url_or_domain_name|
|
11
|
+
actual_code = Util.status(url_or_domain_name)
|
12
|
+
actual_code == expected_code.to_i
|
13
|
+
end
|
14
|
+
|
15
|
+
failure_message do
|
16
|
+
"Received status #{actual_code}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rspec/webservice_matchers/util'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module WebserviceMatchers
|
5
|
+
# Pass when the response code is 200, following redirects
|
6
|
+
# if necessary.
|
7
|
+
RSpec::Matchers.define :be_up do
|
8
|
+
status = nil
|
9
|
+
|
10
|
+
match do |url_or_domain_name|
|
11
|
+
status = Util.status(url_or_domain_name, follow: true)
|
12
|
+
status == 200
|
13
|
+
end
|
14
|
+
|
15
|
+
failure_message do
|
16
|
+
"Received status #{status}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
require 'rspec/webservice_matchers/util'
|
4
|
+
module RSpec
|
5
|
+
module WebserviceMatchers
|
6
|
+
# This is a high level matcher which checks three things:
|
7
|
+
# 1. Permanent redirect
|
8
|
+
# 2. to an https url
|
9
|
+
# 3. which is correctly configured
|
10
|
+
RSpec::Matchers.define :enforce_https_everywhere do
|
11
|
+
error_msg = status = actual_protocol = actual_valid_cert = nil
|
12
|
+
|
13
|
+
match do |domain_name|
|
14
|
+
begin
|
15
|
+
status, headers = Util.head("http://#{domain_name}")
|
16
|
+
new_url = headers['location']
|
17
|
+
/^(?<protocol>https?)/ =~ new_url
|
18
|
+
actual_protocol = protocol || nil
|
19
|
+
actual_valid_cert = Util.valid_ssl_cert?(new_url)
|
20
|
+
(status == 301) &&
|
21
|
+
(actual_protocol == 'https') &&
|
22
|
+
(actual_valid_cert == true)
|
23
|
+
rescue Faraday::Error::ConnectionFailed
|
24
|
+
error_msg = 'Connection failed'
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Create a compound error message listing all of the
|
30
|
+
# relevant actual values received.
|
31
|
+
failure_message do
|
32
|
+
if !error_msg.nil?
|
33
|
+
error_msg
|
34
|
+
else
|
35
|
+
mesgs = []
|
36
|
+
if status != 301
|
37
|
+
mesgs << "received status #{status} instead of 301"
|
38
|
+
end
|
39
|
+
if !actual_protocol.nil? && actual_protocol != 'https'
|
40
|
+
mesgs << "destination uses protocol #{actual_protocol.upcase}"
|
41
|
+
end
|
42
|
+
if !actual_valid_cert
|
43
|
+
mesgs << "there's no valid SSL certificate"
|
44
|
+
end
|
45
|
+
mesgs.join('; ').capitalize
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rspec/webservice_matchers/util'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module WebserviceMatchers
|
5
|
+
# Is https is correctly implemented?
|
6
|
+
RSpec::Matchers.define :have_a_valid_cert do
|
7
|
+
error_message = nil
|
8
|
+
|
9
|
+
match do |domain_name_or_url|
|
10
|
+
begin
|
11
|
+
Util.try_ssl_connection(domain_name_or_url)
|
12
|
+
rescue Exception => e
|
13
|
+
error_message = e.message
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
failure_message do
|
19
|
+
error_message
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rspec/webservice_matchers/util'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module WebserviceMatchers
|
5
|
+
# Do we get a 301 to the place we intend?
|
6
|
+
RSpec::Matchers.define :redirect_permanently_to do |expected|
|
7
|
+
error_message = status = actual_location = nil
|
8
|
+
|
9
|
+
match do |url_or_domain_name|
|
10
|
+
begin
|
11
|
+
status, headers = Util.head(url_or_domain_name)
|
12
|
+
actual_location = headers['location']
|
13
|
+
|
14
|
+
(status == 301) && (/#{expected}\/?/.match(actual_location))
|
15
|
+
rescue Exception => e
|
16
|
+
error_message = e.message
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
failure_message do
|
22
|
+
if !error_message.nil?
|
23
|
+
error_message
|
24
|
+
else
|
25
|
+
mesgs = []
|
26
|
+
if [302, 307].include? status
|
27
|
+
mesgs << "received a temporary redirect, status #{status}"
|
28
|
+
end
|
29
|
+
if !actual_location.nil? && ! (%r|#{expected}/?| === actual_location)
|
30
|
+
mesgs << "received location #{actual_location}"
|
31
|
+
end
|
32
|
+
if ![301, 302, 307].include? status
|
33
|
+
mesgs << "not a redirect: received status #{status}"
|
34
|
+
end
|
35
|
+
mesgs.join('; ').capitalize
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rspec/webservice_matchers/util'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module WebserviceMatchers
|
5
|
+
# Do we get a 302 or 307 to the place we intend?
|
6
|
+
RSpec::Matchers.define :redirect_temporarily_to do |expected|
|
7
|
+
include RSpec
|
8
|
+
error_message = status = actual_location = nil
|
9
|
+
|
10
|
+
match do |url_or_domain_name|
|
11
|
+
begin
|
12
|
+
status, headers = Util.head(url_or_domain_name)
|
13
|
+
actual_location = headers['location']
|
14
|
+
|
15
|
+
[302, 307].include?(status) && (/#{expected}\/?/ =~ actual_location)
|
16
|
+
rescue Exception => e
|
17
|
+
error_message = e.message
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
failure_message do
|
23
|
+
if !error_message.nil?
|
24
|
+
error_message
|
25
|
+
else
|
26
|
+
mesgs = []
|
27
|
+
if status == 301
|
28
|
+
mesgs << "received a permanent redirect, status #{status}"
|
29
|
+
end
|
30
|
+
if !actual_location.nil? && ! (%r|#{expected}/?| === actual_location)
|
31
|
+
mesgs << "received location #{actual_location}"
|
32
|
+
end
|
33
|
+
if ![301, 302, 307].include? status
|
34
|
+
mesgs << "not a redirect: received status #{status}"
|
35
|
+
end
|
36
|
+
mesgs.join('; ').capitalize
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'faraday'
|
3
|
+
require 'faraday_middleware'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
# Seconds
|
7
|
+
TIMEOUT = 20
|
8
|
+
OPEN_TIMEOUT = 20
|
9
|
+
|
10
|
+
module RSpec
|
11
|
+
module WebserviceMatchers
|
12
|
+
# Refactored utility functions
|
13
|
+
module Util
|
14
|
+
def self.status(url_or_domain_name, follow: false)
|
15
|
+
head(url_or_domain_name, follow: follow)[0]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.head(url_or_domain_name, follow: false)
|
19
|
+
url = make_url(url_or_domain_name)
|
20
|
+
response = recheck_on_timeout { connection(follow: follow).head(url) }
|
21
|
+
[response.status, response.headers]
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return true if the given page has status 200,
|
25
|
+
# and follow a few redirects if necessary.
|
26
|
+
def self.up?(url_or_domain_name)
|
27
|
+
url = make_url(url_or_domain_name)
|
28
|
+
conn = connection(follow: true)
|
29
|
+
response = recheck_on_timeout { conn.head(url) }
|
30
|
+
response.status == 200
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.valid_ssl_cert?(domain_name_or_url)
|
34
|
+
try_ssl_connection(domain_name_or_url)
|
35
|
+
true
|
36
|
+
rescue
|
37
|
+
# Not serving SSL, expired, or incorrect domain name in certificate
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.try_ssl_connection(domain_name_or_url)
|
42
|
+
url = "https://#{remove_protocol(domain_name_or_url)}"
|
43
|
+
recheck_on_timeout { connection.head(url) }
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def self.connection(follow: false)
|
50
|
+
Faraday.new do |c|
|
51
|
+
c.options[:timeout] = TIMEOUT
|
52
|
+
c.options[:open_timeout] = OPEN_TIMEOUT
|
53
|
+
c.use(FaradayMiddleware::FollowRedirects, limit: 4) if follow
|
54
|
+
c.adapter :excon
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Ensure that the given string is a URL,
|
59
|
+
# making it into one if necessary.
|
60
|
+
def self.make_url(url_or_domain_name)
|
61
|
+
if %r{^https?://} =~ url_or_domain_name
|
62
|
+
url_or_domain_name
|
63
|
+
else
|
64
|
+
"http://#{url_or_domain_name}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Normalize the input: remove 'http(s)://' if it's there
|
69
|
+
def self.remove_protocol(domain_name_or_url)
|
70
|
+
%r{^https?://(?<name>.+)$} =~ domain_name_or_url
|
71
|
+
name || domain_name_or_url
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.recheck_on_timeout
|
75
|
+
begin
|
76
|
+
yield
|
77
|
+
rescue Faraday::Error::TimeoutError
|
78
|
+
yield
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -1,248 +1,6 @@
|
|
1
|
-
require 'rspec/webservice_matchers/
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
|
7
|
-
# Seconds
|
8
|
-
TIMEOUT = 20
|
9
|
-
OPEN_TIMEOUT = 20
|
10
|
-
|
11
|
-
module RSpec
|
12
|
-
# RSpec Custom Matchers
|
13
|
-
# See https://www.relishapp.com/rspec/rspec-expectations/v/2-3/docs/custom-matchers/define-matcher
|
14
|
-
module WebserviceMatchers
|
15
|
-
# Test whether https is correctly implemented
|
16
|
-
RSpec::Matchers.define :have_a_valid_cert do
|
17
|
-
error_message = nil
|
18
|
-
|
19
|
-
match do |domain_name_or_url|
|
20
|
-
begin
|
21
|
-
WebserviceMatchers.try_ssl_connection(domain_name_or_url)
|
22
|
-
true
|
23
|
-
rescue Exception => e
|
24
|
-
error_message = e.message
|
25
|
-
false
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
failure_message do
|
30
|
-
error_message
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Pass successfully if we get a 301 to the place we intend.
|
35
|
-
RSpec::Matchers.define :redirect_permanently_to do |expected|
|
36
|
-
error_message = actual_status = actual_location = nil
|
37
|
-
|
38
|
-
match do |url_or_domain_name|
|
39
|
-
begin
|
40
|
-
response = WebserviceMatchers.recheck_on_timeout { WebserviceMatchers.connection.head(WebserviceMatchers.make_url url_or_domain_name) }
|
41
|
-
expected = WebserviceMatchers.make_url(expected)
|
42
|
-
actual_location = response.headers['location']
|
43
|
-
actual_status = response.status
|
44
|
-
|
45
|
-
(actual_status == 301) && (/#{expected}\/?/.match(actual_location))
|
46
|
-
rescue Exception => e
|
47
|
-
error_message = e.message
|
48
|
-
false
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
failure_message do
|
53
|
-
if !error_message.nil?
|
54
|
-
error_message
|
55
|
-
else
|
56
|
-
mesgs = []
|
57
|
-
if [302, 307].include? actual_status
|
58
|
-
mesgs << "received a temporary redirect, status #{actual_status}"
|
59
|
-
end
|
60
|
-
if !actual_location.nil? && ! (%r|#{expected}/?| === actual_location)
|
61
|
-
mesgs << "received location #{actual_location}"
|
62
|
-
end
|
63
|
-
if ![301, 302, 307].include? actual_status
|
64
|
-
mesgs << "not a redirect: received status #{actual_status}"
|
65
|
-
end
|
66
|
-
mesgs.join('; ').capitalize
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Pass successfully if we get a 302 or 307 to the place we intend.
|
72
|
-
RSpec::Matchers.define :redirect_temporarily_to do |expected|
|
73
|
-
include RSpec
|
74
|
-
error_message = actual_status = actual_location = nil
|
75
|
-
|
76
|
-
match do |url_or_domain_name|
|
77
|
-
begin
|
78
|
-
response = WebserviceMatchers.recheck_on_timeout { WebserviceMatchers.connection.head(WebserviceMatchers.make_url url_or_domain_name) }
|
79
|
-
expected = WebserviceMatchers.make_url(expected)
|
80
|
-
actual_location = response.headers['location']
|
81
|
-
actual_status = response.status
|
82
|
-
|
83
|
-
[302, 307].include?(actual_status) && (/#{expected}\/?/ =~ actual_location)
|
84
|
-
rescue Exception => e
|
85
|
-
error_message = e.message
|
86
|
-
false
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
failure_message do
|
91
|
-
if !error_message.nil?
|
92
|
-
error_message
|
93
|
-
else
|
94
|
-
mesgs = []
|
95
|
-
if actual_status == 301
|
96
|
-
mesgs << "received a permanent redirect, status #{actual_status}"
|
97
|
-
end
|
98
|
-
if !actual_location.nil? && ! (%r|#{expected}/?| === actual_location)
|
99
|
-
mesgs << "received location #{actual_location}"
|
100
|
-
end
|
101
|
-
if ![301, 302, 307].include? actual_status
|
102
|
-
mesgs << "not a redirect: received status #{actual_status}"
|
103
|
-
end
|
104
|
-
mesgs.join('; ').capitalize
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# This is a high level matcher which checks three things:
|
110
|
-
# 1. Permanent redirect
|
111
|
-
# 2. to an https url
|
112
|
-
# 3. which is correctly configured
|
113
|
-
RSpec::Matchers.define :enforce_https_everywhere do
|
114
|
-
error_msg = actual_status = actual_protocol = actual_valid_cert = nil
|
115
|
-
|
116
|
-
match do |domain_name|
|
117
|
-
begin
|
118
|
-
response = WebserviceMatchers.recheck_on_timeout { WebserviceMatchers.connection.head("http://#{domain_name}") }
|
119
|
-
new_url = response.headers['location']
|
120
|
-
actual_status = response.status
|
121
|
-
/^(?<protocol>https?)/ =~ new_url
|
122
|
-
actual_protocol = protocol || nil
|
123
|
-
actual_valid_cert = WebserviceMatchers.valid_ssl_cert?(new_url)
|
124
|
-
(actual_status == 301) &&
|
125
|
-
(actual_protocol == 'https') &&
|
126
|
-
(actual_valid_cert == true)
|
127
|
-
rescue Faraday::Error::ConnectionFailed
|
128
|
-
error_msg = 'Connection failed'
|
129
|
-
false
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# Create a compound error message listing all of the
|
134
|
-
# relevant actual values received.
|
135
|
-
failure_message do
|
136
|
-
if !error_msg.nil?
|
137
|
-
error_msg
|
138
|
-
else
|
139
|
-
mesgs = []
|
140
|
-
if actual_status != 301
|
141
|
-
mesgs << "received status #{actual_status} instead of 301"
|
142
|
-
end
|
143
|
-
if !actual_protocol.nil? && actual_protocol != 'https'
|
144
|
-
mesgs << "destination uses protocol #{actual_protocol.upcase}"
|
145
|
-
end
|
146
|
-
if !actual_valid_cert
|
147
|
-
mesgs << "there's no valid SSL certificate"
|
148
|
-
end
|
149
|
-
mesgs.join('; ').capitalize
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
end
|
154
|
-
|
155
|
-
# Pass when a URL returns the expected status code
|
156
|
-
# Codes are defined in http://www.rfc-editor.org/rfc/rfc2616.txt
|
157
|
-
RSpec::Matchers.define :be_status do |expected_code|
|
158
|
-
actual_code = nil
|
159
|
-
|
160
|
-
match do |url_or_domain_name|
|
161
|
-
url = WebserviceMatchers.make_url(url_or_domain_name)
|
162
|
-
response = WebserviceMatchers.recheck_on_timeout { WebserviceMatchers.connection.head(url) }
|
163
|
-
actual_code = response.status
|
164
|
-
expected_code = expected_code.to_i
|
165
|
-
actual_code == expected_code
|
166
|
-
end
|
167
|
-
|
168
|
-
failure_message do
|
169
|
-
"Received status #{actual_code}"
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
# Pass when the response code is 200, following redirects
|
174
|
-
# if necessary.
|
175
|
-
RSpec::Matchers.define :be_up do
|
176
|
-
actual_status = nil
|
177
|
-
|
178
|
-
match do |url_or_domain_name|
|
179
|
-
url = WebserviceMatchers.make_url(url_or_domain_name)
|
180
|
-
conn = WebserviceMatchers.connection(follow: true)
|
181
|
-
response = WebserviceMatchers.recheck_on_timeout { conn.head(url) }
|
182
|
-
actual_status = response.status
|
183
|
-
actual_status == 200
|
184
|
-
end
|
185
|
-
|
186
|
-
failure_message do
|
187
|
-
"Received status #{actual_status}"
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
# Return true if the given page has status 200,
|
192
|
-
# and follow a few redirects if necessary.
|
193
|
-
def self.up?(url_or_domain_name)
|
194
|
-
url = make_url(url_or_domain_name)
|
195
|
-
conn = connection(follow: true)
|
196
|
-
response = recheck_on_timeout { conn.head(url) }
|
197
|
-
response.status == 200
|
198
|
-
end
|
199
|
-
|
200
|
-
def self.valid_ssl_cert?(domain_name_or_url)
|
201
|
-
try_ssl_connection(domain_name_or_url)
|
202
|
-
true
|
203
|
-
rescue
|
204
|
-
# Not serving SSL, expired, or incorrect domain name in certificate
|
205
|
-
false
|
206
|
-
end
|
207
|
-
|
208
|
-
def self.try_ssl_connection(domain_name_or_url)
|
209
|
-
recheck_on_timeout { connection.head("https://#{remove_protocol(domain_name_or_url)}") }
|
210
|
-
end
|
211
|
-
|
212
|
-
|
213
|
-
private
|
214
|
-
|
215
|
-
def self.connection(follow: false)
|
216
|
-
Faraday.new do |c|
|
217
|
-
c.options[:timeout] = TIMEOUT
|
218
|
-
c.options[:open_timeout] = OPEN_TIMEOUT
|
219
|
-
c.use(FaradayMiddleware::FollowRedirects, limit: 4) if follow
|
220
|
-
c.adapter :excon
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
# Ensure that the given string is a URL,
|
225
|
-
# making it into one if necessary.
|
226
|
-
def self.make_url(url_or_domain_name)
|
227
|
-
if %r{^https?://} =~ url_or_domain_name
|
228
|
-
url_or_domain_name
|
229
|
-
else
|
230
|
-
"http://#{url_or_domain_name}"
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
# Normalize the input: remove 'http(s)://' if it's there
|
235
|
-
def self.remove_protocol(domain_name_or_url)
|
236
|
-
%r{^https?://(?<name>.+)$} =~ domain_name_or_url
|
237
|
-
name || domain_name_or_url
|
238
|
-
end
|
239
|
-
|
240
|
-
def self.recheck_on_timeout
|
241
|
-
begin
|
242
|
-
yield
|
243
|
-
rescue Faraday::Error::TimeoutError
|
244
|
-
yield
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
end
|
1
|
+
require 'rspec/webservice_matchers/have_a_valid_cert'
|
2
|
+
require 'rspec/webservice_matchers/redirect_permanently_to'
|
3
|
+
require 'rspec/webservice_matchers/redirect_temporarily_to'
|
4
|
+
require 'rspec/webservice_matchers/enforce_https_everywhere'
|
5
|
+
require 'rspec/webservice_matchers/be_status'
|
6
|
+
require 'rspec/webservice_matchers/be_up'
|
@@ -17,11 +17,12 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
19
19
|
spec.require_paths = ['lib']
|
20
|
+
spec.required_ruby_version = '>= 2.1.0'
|
20
21
|
|
21
22
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
23
|
spec.add_development_dependency 'rake'
|
23
24
|
spec.add_development_dependency 'pry'
|
24
|
-
spec.add_development_dependency 'webmock'
|
25
|
+
spec.add_development_dependency 'webmock'
|
25
26
|
|
26
27
|
spec.add_runtime_dependency 'rspec', '~> 3.0'
|
27
28
|
spec.add_runtime_dependency 'excon'
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rspec/webservice_matchers'
|
3
|
+
require 'rspec/webservice_matchers/util'
|
3
4
|
|
4
5
|
describe 'be_status' do
|
5
6
|
it 'can check 200 for successful resource requests' do
|
@@ -44,7 +45,7 @@ describe 'be_up' do
|
|
44
45
|
end
|
45
46
|
|
46
47
|
it 'is available via a public API' do
|
47
|
-
expect(RSpec::WebserviceMatchers.up?('http://www.website.com/')).to be true
|
48
|
+
expect(RSpec::WebserviceMatchers::Util.up?('http://www.website.com/')).to be true
|
48
49
|
end
|
49
50
|
|
50
51
|
it 'gives relevant error output' do
|
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'rspec/webservice_matchers'
|
2
|
+
require 'rspec/webservice_matchers/util'
|
3
|
+
include RSpec::WebserviceMatchers
|
3
4
|
|
4
5
|
describe '#up?' do
|
5
6
|
it 'follows redirects when necessary' do
|
6
|
-
expect(
|
7
|
-
expect(
|
7
|
+
expect(Util.up?('perm-redirector.com')).to be_truthy
|
8
|
+
expect(Util.up?('temp-redirector.org')).to be_truthy
|
8
9
|
end
|
9
10
|
|
10
11
|
it 'retries timeout errors once' do
|
11
|
-
expect(
|
12
|
+
expect(Util.up?('http://www.timeout-once.com')).to be_truthy
|
12
13
|
end
|
13
14
|
end
|
@@ -26,11 +26,12 @@ describe 'have_a_valid_cert matcher' do
|
|
26
26
|
}.to fail_matching(/not known/i)
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
# TODO: Find a good way to test this.
|
30
|
+
# it 'provides a good error message if the request times out' do
|
31
|
+
# expect {
|
32
|
+
# expect('www.myapp.com').to have_a_valid_cert
|
33
|
+
# }.to fail_matching(/(timeout)|(execution expired)/)
|
34
|
+
# end
|
34
35
|
end
|
35
36
|
|
36
37
|
# See https://www.eff.org/https-everywhere
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-webservice_matchers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robb Shecter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,6 +136,13 @@ files:
|
|
136
136
|
- README.md
|
137
137
|
- Rakefile
|
138
138
|
- lib/rspec/webservice_matchers.rb
|
139
|
+
- lib/rspec/webservice_matchers/be_status.rb
|
140
|
+
- lib/rspec/webservice_matchers/be_up.rb
|
141
|
+
- lib/rspec/webservice_matchers/enforce_https_everywhere.rb
|
142
|
+
- lib/rspec/webservice_matchers/have_a_valid_cert.rb
|
143
|
+
- lib/rspec/webservice_matchers/redirect_permanently_to.rb
|
144
|
+
- lib/rspec/webservice_matchers/redirect_temporarily_to.rb
|
145
|
+
- lib/rspec/webservice_matchers/util.rb
|
139
146
|
- lib/rspec/webservice_matchers/version.rb
|
140
147
|
- rspec-webservice_matchers.gemspec
|
141
148
|
- spec/rspec/webservice_matchers/protcol_spec.rb
|
@@ -155,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
162
|
requirements:
|
156
163
|
- - ">="
|
157
164
|
- !ruby/object:Gem::Version
|
158
|
-
version:
|
165
|
+
version: 2.1.0
|
159
166
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
167
|
requirements:
|
161
168
|
- - ">="
|
@@ -163,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
170
|
version: '0'
|
164
171
|
requirements: []
|
165
172
|
rubyforge_project:
|
166
|
-
rubygems_version: 2.4.
|
173
|
+
rubygems_version: 2.4.6
|
167
174
|
signing_key:
|
168
175
|
specification_version: 4
|
169
176
|
summary: Black-box web app configuration testing
|