rspec-webservice_matchers 2.0 → 3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +9 -10
- data/lib/rspec/webservice_matchers.rb +16 -7
- data/lib/rspec/webservice_matchers/version.rb +1 -1
- data/rspec-webservice_matchers.gemspec +16 -16
- data/spec/rspec/webservice_matchers/protcol_spec.rb +8 -2
- data/spec/rspec/webservice_matchers/public_api_spec.rb +13 -0
- data/spec/rspec/webservice_matchers/redirect_spec.rb +6 -8
- data/spec/spec_helper.rb +10 -7
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da5e8521d806264714169e3d9427a4cccfd979d9
|
4
|
+
data.tar.gz: 9b3c233b836035216d277fbbf687b5873531064e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ce03e800829b9c0b6bb9976d355d154821da201e92995c10a0989b0c2e295a357464dcfd7aa1573b2b8f1a0d58c15378b4d4cb1b74dac2660f7bf0551506267
|
7
|
+
data.tar.gz: f5abc5dafeeddfe2b4648fb81671874972bacfe8cdc4f3acd605617f5b320ffe741fa67af24fb1c99e6c3c7fab8f03757728be4622c73d885561017a2a63cc58
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,10 @@
|
|
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)
|
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)
|
4
4
|
|
5
|
-
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
|
5
|
+
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
6
|
|
7
|
-
This library takes a
|
8
|
-
and so you can use your own RSpec writing style; there's no new DSL to learn.
|
7
|
+
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
8
|
|
10
9
|
Installation
|
11
10
|
------------
|
@@ -19,12 +18,12 @@ These new RSpec matchers:
|
|
19
18
|
|
20
19
|
| Notes
|
21
20
|
-------------------------------|------------------------------------------------
|
22
|
-
**be_status** |
|
23
|
-
**be_up** |
|
24
|
-
**have_a_valid_cert** |
|
25
|
-
**enforce_https_everywhere** | See the [EFF project](https://www.eff.org/https-everywhere)
|
26
|
-
**redirect_permanently_to** | Checks for 301
|
27
|
-
**redirect_temporarily_to** | Checks for 302 or 307
|
21
|
+
**be_status** | A low-level matcher to explicitly check for a 200, 503, or any other code
|
22
|
+
**be_up** | Looks for a 200, but will follow up to four redirects
|
23
|
+
**have_a_valid_cert** | Will fail if there's no cert, or it's expired or incorrectly configured
|
24
|
+
**enforce_https_everywhere** | Passes if the site will _only_ allow SSL connections. See the [EFF project, HTTP Everywhere](https://www.eff.org/https-everywhere)
|
25
|
+
**redirect_permanently_to** | Checks for 301 and a correct destination URL
|
26
|
+
**redirect_temporarily_to** | Checks for 302 or 307 and a correct destination
|
28
27
|
|
29
28
|
|
30
29
|
Example
|
@@ -36,7 +36,7 @@ module RSpec
|
|
36
36
|
|
37
37
|
match do |url_or_domain_name|
|
38
38
|
begin
|
39
|
-
response = WebserviceMatchers.connection.head(WebserviceMatchers.make_url url_or_domain_name)
|
39
|
+
response = WebserviceMatchers.recheck_on_timeout { WebserviceMatchers.connection.head(WebserviceMatchers.make_url url_or_domain_name) }
|
40
40
|
expected = WebserviceMatchers.make_url(expected)
|
41
41
|
actual_location = response.headers['location']
|
42
42
|
actual_status = response.status
|
@@ -74,7 +74,7 @@ module RSpec
|
|
74
74
|
|
75
75
|
match do |url_or_domain_name|
|
76
76
|
begin
|
77
|
-
response = WebserviceMatchers.connection.head(WebserviceMatchers.make_url url_or_domain_name)
|
77
|
+
response = WebserviceMatchers.recheck_on_timeout { WebserviceMatchers.connection.head(WebserviceMatchers.make_url url_or_domain_name) }
|
78
78
|
expected = WebserviceMatchers.make_url(expected)
|
79
79
|
actual_location = response.headers['location']
|
80
80
|
actual_status = response.status
|
@@ -114,7 +114,7 @@ module RSpec
|
|
114
114
|
|
115
115
|
match do |domain_name|
|
116
116
|
begin
|
117
|
-
response = WebserviceMatchers.connection.head("http://#{domain_name}")
|
117
|
+
response = WebserviceMatchers.recheck_on_timeout { WebserviceMatchers.connection.head("http://#{domain_name}") }
|
118
118
|
new_url = response.headers['location']
|
119
119
|
actual_status = response.status
|
120
120
|
/^(?<protocol>https?)/ =~ new_url
|
@@ -158,7 +158,7 @@ module RSpec
|
|
158
158
|
|
159
159
|
match do |url_or_domain_name|
|
160
160
|
url = WebserviceMatchers.make_url(url_or_domain_name)
|
161
|
-
response = WebserviceMatchers.connection.head(url)
|
161
|
+
response = WebserviceMatchers.recheck_on_timeout { WebserviceMatchers.connection.head(url) }
|
162
162
|
actual_code = response.status
|
163
163
|
expected_code = expected_code.to_i
|
164
164
|
actual_code == expected_code
|
@@ -177,7 +177,7 @@ module RSpec
|
|
177
177
|
match do |url_or_domain_name|
|
178
178
|
url = WebserviceMatchers.make_url(url_or_domain_name)
|
179
179
|
conn = WebserviceMatchers.connection(follow: true)
|
180
|
-
response = conn.head(url)
|
180
|
+
response = WebserviceMatchers.recheck_on_timeout { conn.head(url) }
|
181
181
|
actual_status = response.status
|
182
182
|
actual_status == 200
|
183
183
|
end
|
@@ -192,7 +192,7 @@ module RSpec
|
|
192
192
|
def self.up?(url_or_domain_name)
|
193
193
|
url = make_url(url_or_domain_name)
|
194
194
|
conn = connection(follow: true)
|
195
|
-
response = conn.head(url)
|
195
|
+
response = recheck_on_timeout { conn.head(url) }
|
196
196
|
response.status == 200
|
197
197
|
end
|
198
198
|
|
@@ -205,9 +205,10 @@ module RSpec
|
|
205
205
|
end
|
206
206
|
|
207
207
|
def self.try_ssl_connection(domain_name_or_url)
|
208
|
-
connection.head("https://#{remove_protocol(domain_name_or_url)}")
|
208
|
+
recheck_on_timeout { connection.head("https://#{remove_protocol(domain_name_or_url)}") }
|
209
209
|
end
|
210
210
|
|
211
|
+
|
211
212
|
private
|
212
213
|
|
213
214
|
def self.connection(follow: false)
|
@@ -234,5 +235,13 @@ module RSpec
|
|
234
235
|
%r{^https?://(?<name>.+)$} =~ domain_name_or_url
|
235
236
|
name || domain_name_or_url
|
236
237
|
end
|
238
|
+
|
239
|
+
def self.recheck_on_timeout
|
240
|
+
begin
|
241
|
+
yield
|
242
|
+
rescue Faraday::Error::TimeoutError
|
243
|
+
yield
|
244
|
+
end
|
245
|
+
end
|
237
246
|
end
|
238
247
|
end
|
@@ -4,25 +4,25 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'rspec/webservice_matchers/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.description
|
12
|
-
spec.summary
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
7
|
+
spec.name = 'rspec-webservice_matchers'
|
8
|
+
spec.version = RSpec::WebserviceMatchers::VERSION
|
9
|
+
spec.authors = ['Robb Shecter']
|
10
|
+
spec.email = ['robb@weblaws.org']
|
11
|
+
spec.description = 'Black-box web app configuration testing'
|
12
|
+
spec.summary = 'Black-box web app configuration testing'
|
13
|
+
spec.homepage = 'https://github.com/dogweather/rspec-webservice_matchers'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
|
-
spec.files = `git ls-files`.split(
|
17
|
-
spec.executables = spec.files.grep(
|
18
|
-
spec.test_files = spec.files.grep(
|
19
|
-
spec.require_paths = [
|
16
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
|
+
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'pry'
|
24
24
|
spec.add_development_dependency 'webmock'
|
25
|
-
spec.add_development_dependency
|
25
|
+
spec.add_development_dependency 'codeclimate-test-reporter'
|
26
26
|
|
27
27
|
spec.add_runtime_dependency 'rspec', '~> 2'
|
28
28
|
spec.add_runtime_dependency 'faraday'
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rspec/webservice_matchers'
|
3
3
|
|
4
|
-
|
5
4
|
describe 'be_status' do
|
6
5
|
it 'can check 200 for successful resource requests' do
|
7
6
|
'http://a-page.com/a/page.txt'.should be_status 200
|
@@ -28,8 +27,11 @@ describe 'be_status' do
|
|
28
27
|
expect('http://notfound.com/no.txt').to be_status 200
|
29
28
|
}.to fail_matching(/404/)
|
30
29
|
end
|
31
|
-
end
|
32
30
|
|
31
|
+
it 'succeeds even if the site times out on the first try' do
|
32
|
+
'http://www.timeout-once.com'.should be_status 200
|
33
|
+
end
|
34
|
+
end
|
33
35
|
|
34
36
|
describe 'be_up' do
|
35
37
|
it 'follows redirects when necessary' do
|
@@ -50,4 +52,8 @@ describe 'be_up' do
|
|
50
52
|
expect('http://notfound.com/no.txt').to be_up
|
51
53
|
}.to fail_matching(/404/)
|
52
54
|
end
|
55
|
+
|
56
|
+
it 'succeeds even if the site times out on the first try' do
|
57
|
+
'http://www.timeout-once.com'.should be_up
|
58
|
+
end
|
53
59
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rspec/webservice_matchers'
|
3
|
+
|
4
|
+
describe '#up?' do
|
5
|
+
it 'follows redirects when necessary' do
|
6
|
+
RSpec::WebserviceMatchers.up?('perm-redirector.com').should be_true
|
7
|
+
RSpec::WebserviceMatchers.up?('temp-redirector.org').should be_true
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'retries timeout errors once' do
|
11
|
+
RSpec::WebserviceMatchers.up?('http://www.timeout-once.com').should be_true
|
12
|
+
end
|
13
|
+
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rspec/webservice_matchers'
|
3
3
|
|
4
|
-
|
5
4
|
describe 'redirect_permanently_to' do
|
6
5
|
it 'passes when receiving a 301 to the given URL' do
|
7
|
-
expect('http://perm-redirector.com').to redirect_permanently_to 'http://www.website.com/'
|
6
|
+
expect('http://perm-redirector.com').to redirect_permanently_to 'http://www.website.com/'
|
8
7
|
end
|
9
8
|
|
10
9
|
it 'handles domain names gracefully' do
|
@@ -13,7 +12,7 @@ describe 'redirect_permanently_to' do
|
|
13
12
|
|
14
13
|
it 'handles a missing final slash' do
|
15
14
|
expect('perm-redirector.com').to redirect_permanently_to 'www.website.com'
|
16
|
-
end
|
15
|
+
end
|
17
16
|
|
18
17
|
it 'gives a good error message for the wrong redirect type' do
|
19
18
|
expect {
|
@@ -30,17 +29,16 @@ describe 'redirect_permanently_to' do
|
|
30
29
|
it 'gives a good error message for a non-redirect status' do
|
31
30
|
expect {
|
32
31
|
expect('notfound.com').to redirect_permanently_to 'http://the-wrong-site.com/'
|
33
|
-
}.to fail_matching(/404/i)
|
32
|
+
}.to fail_matching(/404/i)
|
34
33
|
end
|
35
34
|
|
36
35
|
it 'gives a good error message when the hostname is bad' do
|
37
36
|
expect {
|
38
37
|
expect('asdhfjadhsfksd.com').to redirect_permanently_to 'http://the-wrong-site.com/'
|
39
|
-
}.to fail_matching(/not known/i)
|
40
|
-
end
|
38
|
+
}.to fail_matching(/not known/i)
|
39
|
+
end
|
41
40
|
end
|
42
41
|
|
43
|
-
|
44
42
|
describe 'redirect_temporarily_to' do
|
45
43
|
it 'passes when it gets a 302' do
|
46
44
|
'http://temp-redirector.org'.should redirect_temporarily_to 'http://a-page.com/a/page.txt'
|
@@ -48,7 +46,7 @@ describe 'redirect_temporarily_to' do
|
|
48
46
|
|
49
47
|
it 'handles domain names gracefully' do
|
50
48
|
'temp-redirector.org'.should redirect_temporarily_to 'a-page.com/a/page.txt'
|
51
|
-
end
|
49
|
+
end
|
52
50
|
|
53
51
|
it 'passes when it gets a 307' do
|
54
52
|
'temp-307-redirector.net'.should redirect_temporarily_to 'a-page.com/a/page.txt'
|
data/spec/spec_helper.rb
CHANGED
@@ -1,31 +1,34 @@
|
|
1
|
-
require
|
1
|
+
require 'codeclimate-test-reporter'
|
2
2
|
CodeClimate::TestReporter.start
|
3
3
|
|
4
4
|
require 'webmock/rspec'
|
5
5
|
|
6
6
|
RSpec.configure do |config|
|
7
7
|
config.before(:each) do
|
8
|
-
|
9
8
|
WebMock.stub_request :any, 'http://a-page.com/a/page.txt'
|
10
9
|
WebMock.stub_request :any, 'www.website.com'
|
11
10
|
WebMock.stub_request(:any, /notfound.com/).to_return(status: 404)
|
12
11
|
WebMock.stub_request(:any, 'outoforder.com').to_return(status: 503)
|
13
12
|
|
14
13
|
WebMock.stub_request(:any, 'perm-redirector.com')
|
15
|
-
.to_return(status: 301, headers: {Location: 'http://www.website.com/'})
|
14
|
+
.to_return(status: 301, headers: { Location: 'http://www.website.com/' })
|
16
15
|
|
17
16
|
WebMock.stub_request(:any, 'temp-redirector.org')
|
18
|
-
.to_return(status: 302, headers: {Location: 'http://a-page.com/a/page.txt'})
|
17
|
+
.to_return(status: 302, headers: { Location: 'http://a-page.com/a/page.txt' })
|
19
18
|
|
20
19
|
WebMock.stub_request(:any, 'temp-307-redirector.net')
|
21
|
-
.to_return(status: 307, headers: {Location: 'http://a-page.com/a/page.txt'})
|
20
|
+
.to_return(status: 307, headers: { Location: 'http://a-page.com/a/page.txt' })
|
21
|
+
|
22
|
+
# Timeout scenarios
|
23
|
+
WebMock.stub_request(:any, 'www.timeout.com').to_timeout
|
24
|
+
WebMock.stub_request(:any, 'www.timeout-once.com').to_timeout.then.to_return({body: 'abc'})
|
22
25
|
|
23
26
|
WebMock.allow_net_connect!
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
27
|
-
|
28
30
|
module RSpec
|
31
|
+
# Matchers to help test RSpec matchers
|
29
32
|
module Matchers
|
30
33
|
def fail
|
31
34
|
raise_error(RSpec::Expectations::ExpectationNotMetError)
|
@@ -39,4 +42,4 @@ module RSpec
|
|
39
42
|
raise_error(RSpec::Expectations::ExpectationNotMetError, regex)
|
40
43
|
end
|
41
44
|
end
|
42
|
-
end
|
45
|
+
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
|
+
version: '3.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robb Shecter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- lib/rspec/webservice_matchers/version.rb
|
140
140
|
- rspec-webservice_matchers.gemspec
|
141
141
|
- spec/rspec/webservice_matchers/protcol_spec.rb
|
142
|
+
- spec/rspec/webservice_matchers/public_api_spec.rb
|
142
143
|
- spec/rspec/webservice_matchers/redirect_spec.rb
|
143
144
|
- spec/rspec/webservice_matchers/ssl_spec.rb
|
144
145
|
- spec/spec_helper.rb
|
@@ -168,6 +169,7 @@ specification_version: 4
|
|
168
169
|
summary: Black-box web app configuration testing
|
169
170
|
test_files:
|
170
171
|
- spec/rspec/webservice_matchers/protcol_spec.rb
|
172
|
+
- spec/rspec/webservice_matchers/public_api_spec.rb
|
171
173
|
- spec/rspec/webservice_matchers/redirect_spec.rb
|
172
174
|
- spec/rspec/webservice_matchers/ssl_spec.rb
|
173
175
|
- spec/spec_helper.rb
|