rspec-webservice_matchers 4.0.1 → 4.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4356f7c49634e7a88471c05598307e27aaf5fbd
4
- data.tar.gz: cdb55236a82a22067581d25ee24591470d658047
3
+ metadata.gz: a235a451fd315c776f1f3d3b11755e2d93c88b73
4
+ data.tar.gz: 3826ce984adaae4a9cb9b49b361bd7f3b9aab6bf
5
5
  SHA512:
6
- metadata.gz: 9c68cb9ac58edc93ae5cf0d16873a342e3d547ad32c35463fa0a315be5ac1d9d046d67ffede36e6dd4b46c254cea002504cb08ee16b8073192661e09d2fce550
7
- data.tar.gz: df52ce370c307c92136d5da95cd3d361545d2b0674db8c19a7eca50e28d08e606becffc5a45da26d51de8d63f21c23302ff97679e529bee460b6dc87f5fe51e8
6
+ metadata.gz: 831a900c20d355fa637fd9f2b8146737457e379e4b1a22e8dd528a09de48fea8d5695e99e706a84887d593c1ea64c199a07ae4e937259b4645416fabb590aff4
7
+ data.tar.gz: a9b1d9a7a937a0ec451f40d3198b47d9b1868d1b5849211ca094d626f3b260d35fc8a9ea6fac3d67fd6f0ffe3e5d3565b3b0cce39d1ffa31779714151e66551c
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # RSpec::WebserviceMatchers
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/rspec-webservice_matchers.png)](http://badge.fury.io/rb/rspec-webservice_matchers) [![Build Status](https://travis-ci.org/dogweather/rspec-webservice_matchers.png?branch=master)](https://travis-ci.org/dogweather/rspec-webservice_matchers) [![Code Climate](https://codeclimate.com/github/dogweather/rspec-webservice_matchers.png)](https://codeclimate.com/github/dogweather/rspec-webservice_matchers)
3
+ [![Gem Version](https://badge.fury.io/rb/rspec-webservice_matchers.png)](http://badge.fury.io/rb/rspec-webservice_matchers) [![Code Climate](https://codeclimate.com/github/dogweather/rspec-webservice_matchers.png)](https://codeclimate.com/github/dogweather/rspec-webservice_matchers)
4
4
 
5
5
 
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.
6
+ A [gem](https://rubygems.org/gems/rspec-webservice_matchers) to black-box test a web server configuration. For example, whether a site's 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 my motivations.
7
7
 
8
8
  This library takes a minimalist approach: it simply adds new RSpec matchers. Therefore, you can use your own RSpec writing style; there's no new DSL to learn.
9
9
 
@@ -36,7 +36,7 @@ Here's an example which uses them all:
36
36
  ```Ruby
37
37
  require 'rspec/webservice_matchers'
38
38
 
39
- describe 'My app' do
39
+ describe 'My app' do
40
40
  context 'www.myapp.com' do
41
41
  it { should be_up }
42
42
  it { should have_a_valid_cert }
@@ -60,5 +60,3 @@ Related Projects
60
60
  ----------------
61
61
  * [serverspec](http://serverspec.org)
62
62
  * [HTTP Assertions](https://github.com/dogweather/HTTP-Assertions): A precusor to this library. Written in the older test case / assert style.
63
-
64
-
@@ -2,18 +2,20 @@ require 'rspec/webservice_matchers/util'
2
2
 
3
3
  module RSpec
4
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}"
5
+ module BeStatus
6
+ # Pass when a URL returns the expected status code
7
+ # Codes are defined in http://www.rfc-editor.org/rfc/rfc2616.txt
8
+ RSpec::Matchers.define :be_status do |expected_code|
9
+ actual_code = nil
10
+
11
+ match do |url_or_domain_name|
12
+ actual_code = Util.status(url_or_domain_name)
13
+ actual_code == expected_code.to_i
14
+ end
15
+
16
+ failure_message do
17
+ "Received status #{actual_code}"
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -2,18 +2,20 @@ require 'rspec/webservice_matchers/util'
2
2
 
3
3
  module RSpec
4
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
5
+ module BeUp
6
+ # Pass when the response code is 200, following redirects
7
+ # if necessary.
8
+ RSpec::Matchers.define :be_up do
9
+ status = nil
9
10
 
10
- match do |url_or_domain_name|
11
- status = Util.status(url_or_domain_name, follow: true)
12
- status == 200
13
- end
11
+ match do |url_or_domain_name|
12
+ status = Util.status(url_or_domain_name, follow: true)
13
+ status == 200
14
+ end
14
15
 
15
- failure_message do
16
- "Received status #{status}"
16
+ failure_message do
17
+ "Received status #{status}"
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -1,47 +1,51 @@
1
1
  require 'faraday'
2
-
3
2
  require 'rspec/webservice_matchers/util'
3
+
4
4
  module RSpec
5
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
6
+ module EnforceHttpsEverywhere
7
+ # This is a high level matcher which checks three things:
8
+ # 1. Permanent redirect
9
+ # 2. to an https url
10
+ # 3. which is correctly configured
11
+ RSpec::Matchers.define :enforce_https_everywhere do
12
+ error_msg = status = final_protocol = has_valid_cert = nil
13
+
14
+ match do |domain_name|
15
+ begin
16
+ status, new_url, final_protocol = get_info(domain_name)
17
+ meets_expectations?(status, final_protocol, Util.valid_cert?(new_url))
18
+ rescue Faraday::Error::ConnectionFailed
19
+ error_msg = 'Connection failed'
20
+ false
21
+ end
22
+ end
12
23
 
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
24
+ def get_info(domain_name)
25
+ status, headers = Util.head(domain_name)
26
+ location = headers['location']
27
+ /^(https?)/ =~ location
28
+ protocol = $1 || nil
29
+ [status, location, protocol]
26
30
  end
27
- end
28
31
 
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
32
+ def meets_expectations?(status, protocol, valid_cert)
33
+ (status == 301) && (protocol == 'https') && valid_cert
34
+ end
35
+
36
+ # Create a compound error message listing all of the
37
+ # relevant actual values received.
38
+ failure_message do
39
+ error_msg || higher_level_errors(status, final_protocol, has_valid_cert)
40
+ end
41
+
42
+ def higher_level_errors(status, protocol, cert_is_valid)
35
43
  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
+ mesgs << "received status #{status} instead of 301" if status != 301
45
+ if !protocol.nil? && protocol != 'https'
46
+ mesgs << "destination uses protocol #{protocol.upcase}"
44
47
  end
48
+ mesgs << "there's no valid SSL certificate" unless cert_is_valid
45
49
  mesgs.join('; ').capitalize
46
50
  end
47
51
  end
@@ -2,21 +2,23 @@ require 'rspec/webservice_matchers/util'
2
2
 
3
3
  module RSpec
4
4
  module WebserviceMatchers
5
- # Is https is correctly implemented?
6
- RSpec::Matchers.define :have_a_valid_cert do
7
- error_message = nil
5
+ module HaveAValidCert
6
+ # Is https is correctly implemented?
7
+ RSpec::Matchers.define :have_a_valid_cert do
8
+ error_message = nil
8
9
 
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
10
+ match do |domain_name_or_url|
11
+ begin
12
+ Util.try_ssl_connection(domain_name_or_url)
13
+ rescue Exception => e
14
+ error_message = e.message
15
+ false
16
+ end
15
17
  end
16
- end
17
18
 
18
- failure_message do
19
- error_message
19
+ failure_message do
20
+ error_message
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -2,37 +2,43 @@ require 'rspec/webservice_matchers/util'
2
2
 
3
3
  module RSpec
4
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
5
+ module RedirectPermanentlyTo
6
+ # Do we get a 301 to the place we intend?
7
+ RSpec::Matchers.define :redirect_permanently_to do |expected|
8
+ include RSpec
9
+ exception = status = actual_location = nil
8
10
 
9
- match do |url_or_domain_name|
10
- begin
11
- status, headers = Util.head(url_or_domain_name)
12
- actual_location = headers['location']
11
+ match do |url_or_domain_name|
12
+ begin
13
+ status, headers = Util.head(url_or_domain_name)
14
+ actual_location = headers['location']
13
15
 
14
- (status == 301) && (/#{expected}\/?/.match(actual_location))
15
- rescue Exception => e
16
- error_message = e.message
17
- false
16
+ Util.permanent_redirect?(status) &&
17
+ expected_location?(expected, actual_location)
18
+ rescue Exception => e
19
+ exception = e
20
+ false
21
+ end
18
22
  end
19
- end
20
23
 
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}"
24
+ failure_message do
25
+ return Util.error_message(exception) if exception
26
+
27
+ errors = []
28
+ if Util.temp_redirect? status
29
+ errors << "received a temporary redirect, status #{status}"
28
30
  end
29
- if !actual_location.nil? && ! (%r|#{expected}/?| === actual_location)
30
- mesgs << "received location #{actual_location}"
31
+ unless expected_location?(expected, actual_location)
32
+ errors << "received location #{actual_location}"
31
33
  end
32
- if ![301, 302, 307].include? status
33
- mesgs << "not a redirect: received status #{status}"
34
+ unless Util.redirect? status
35
+ errors << "not a redirect: received status #{status}"
34
36
  end
35
- mesgs.join('; ').capitalize
37
+ Util.error_message(errors)
38
+ end
39
+
40
+ def expected_location?(expected, actual)
41
+ actual =~ %r{#{expected}/?}
36
42
  end
37
43
  end
38
44
  end
@@ -2,38 +2,44 @@ require 'rspec/webservice_matchers/util'
2
2
 
3
3
  module RSpec
4
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
5
+ module RedirectTemporarilyTo
6
+ # Do we get a 302 or 307 to the place we intend?
7
+ RSpec::Matchers.define :redirect_temporarily_to do |expected|
8
+ include RSpec
9
+ status = actual_location = exception = nil
9
10
 
10
- match do |url_or_domain_name|
11
- begin
12
- status, headers = Util.head(url_or_domain_name)
13
- actual_location = headers['location']
11
+ match do |url_or_domain_name|
12
+ begin
13
+ status, headers = Util.head(url_or_domain_name)
14
+ actual_location = headers['location']
14
15
 
15
- [302, 307].include?(status) && (/#{expected}\/?/ =~ actual_location)
16
- rescue Exception => e
17
- error_message = e.message
18
- false
16
+ Util.temp_redirect?(status) &&
17
+ expected_location?(expected, actual_location)
18
+ rescue Exception => e
19
+ exception = e
20
+ false
21
+ end
19
22
  end
20
- end
21
23
 
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}"
24
+ failure_message do
25
+ return Util.error_message(exception) if exception
26
+
27
+ errors = []
28
+ if Util.permanent_redirect? status
29
+ errors << 'received a permanent redirect'
29
30
  end
30
- if !actual_location.nil? && ! (%r|#{expected}/?| === actual_location)
31
- mesgs << "received location #{actual_location}"
31
+ unless expected_location? expected, actual_location
32
+ errors << "received location #{actual_location}"
32
33
  end
33
- if ![301, 302, 307].include? status
34
- mesgs << "not a redirect: received status #{status}"
34
+ unless Util.redirect? status
35
+ errors << "not a redirect: received status #{status}"
35
36
  end
36
- mesgs.join('; ').capitalize
37
+
38
+ Util.error_message(errors)
39
+ end
40
+
41
+ def expected_location?(expected, actual)
42
+ actual =~ %r{#{expected}/?}
37
43
  end
38
44
  end
39
45
  end
@@ -3,14 +3,33 @@ require 'faraday'
3
3
  require 'faraday_middleware'
4
4
  require 'pry'
5
5
 
6
- # Seconds
7
- TIMEOUT = 20
8
- OPEN_TIMEOUT = 20
6
+ TIMEOUT_IN_SECONDS = 20
7
+ OPEN_TIMEOUT_IN_SECONDS = 20
9
8
 
10
9
  module RSpec
11
10
  module WebserviceMatchers
12
- # Refactored utility functions
13
11
  module Util
12
+ def self.error_message(errors)
13
+ return errors.message if errors.respond_to?(:message)
14
+
15
+ errors
16
+ .map(&:to_s)
17
+ .join('; ')
18
+ .capitalize
19
+ end
20
+
21
+ def self.redirect?(status)
22
+ temp_redirect?(status) || permanent_redirect?(status)
23
+ end
24
+
25
+ def self.temp_redirect?(status)
26
+ [302, 307].include?(status)
27
+ end
28
+
29
+ def self.permanent_redirect?(status)
30
+ status == 301
31
+ end
32
+
14
33
  def self.status(url_or_domain_name, follow: false)
15
34
  head(url_or_domain_name, follow: follow)[0]
16
35
  end
@@ -30,7 +49,7 @@ module RSpec
30
49
  response.status == 200
31
50
  end
32
51
 
33
- def self.valid_ssl_cert?(domain_name_or_url)
52
+ def self.valid_cert?(domain_name_or_url)
34
53
  try_ssl_connection(domain_name_or_url)
35
54
  true
36
55
  rescue
@@ -48,8 +67,8 @@ module RSpec
48
67
 
49
68
  def self.connection(follow: false)
50
69
  Faraday.new do |c|
51
- c.options[:timeout] = TIMEOUT
52
- c.options[:open_timeout] = OPEN_TIMEOUT
70
+ c.options[:timeout] = TIMEOUT_IN_SECONDS
71
+ c.options[:open_timeout] = OPEN_TIMEOUT_IN_SECONDS
53
72
  c.use(FaradayMiddleware::FollowRedirects, limit: 4) if follow
54
73
  c.adapter :excon
55
74
  end
@@ -72,11 +91,9 @@ module RSpec
72
91
  end
73
92
 
74
93
  def self.recheck_on_timeout
75
- begin
76
- yield
77
- rescue Faraday::Error::TimeoutError
78
- yield
79
- end
94
+ yield
95
+ rescue Faraday::Error::TimeoutError
96
+ yield
80
97
  end
81
98
  end
82
99
  end
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module WebserviceMatchers
3
- VERSION = '4.0.1'
3
+ VERSION = '4.0.2'
4
4
  end
5
5
  end
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.1
4
+ version: 4.0.2
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-03-12 00:00:00.000000000 Z
11
+ date: 2016-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -170,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
170
170
  version: '0'
171
171
  requirements: []
172
172
  rubyforge_project:
173
- rubygems_version: 2.4.6
173
+ rubygems_version: 2.5.0
174
174
  signing_key:
175
175
  specification_version: 4
176
176
  summary: Black-box web app configuration testing