remote_http_testing 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in remote_http_testing.gemspec
4
+ gemspec
data/README.markdown ADDED
@@ -0,0 +1,60 @@
1
+ Remote Http Testing
2
+ ===================
3
+
4
+ This module helps write integration tests which make HTTP requests to remote servers. Unlike Rack::Test, it doesn't make requests to an in-process Rack server. It uses Net::HTTP for making requests.
5
+
6
+ Usage
7
+ =====
8
+ To use it, mix it in to your test case, specify the server your integration test is talking to, and begin
9
+ making requests.
10
+
11
+ require "remote_http_testing"
12
+
13
+ class MyServiceIntegrationTest < Scope::TestCase
14
+
15
+ # This is the server all HTTP requests will be made to.
16
+ def server
17
+ "http://localhost:3000"
18
+ end
19
+
20
+ setup_once do
21
+ ensure_reachable!(server)
22
+ end
23
+
24
+ should "return a '401 Unauthorized' response when unaunthenticated" do
25
+ get "/users/123/profile"
26
+ assert_status 401
27
+ end
28
+ end
29
+
30
+ Reference
31
+ =========
32
+ These methods are available to your test.
33
+
34
+ delete(url, params)
35
+
36
+ get(url, params)
37
+
38
+ patch(url, params)
39
+
40
+ post(url, params)
41
+
42
+ put(url, params)
43
+
44
+ last_response() - a Net::HTTPResponse object. Use last_response.body to get the response body.
45
+
46
+ dom_response() - The response body parsed using Nokogiri::HTML().
47
+
48
+ json_respones() - A hash of the response body, parsed using JSON.parse().
49
+
50
+ assert_status(status_code, optional_helpful_message)
51
+
52
+ ensure_reachable!(server_url, optional_server_display_name) - Exits if the given server is not reachable.
53
+
54
+ Development
55
+ ===========
56
+ When working on this gem, after you've made changes, you can include your modified gem into any app which uses bundler by adding the `:path` option in your Gemfile:
57
+
58
+ gem "remote_http_testing", :path => "~/path/to/remote_http_testing_repo"
59
+
60
+ Then run `bundle install` from within your app. The installed gem is now symlinked to your local working copy of the gem.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ # Bundler provides some helpful gem creation and publishing tasks. `rake -T` to see them.
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,122 @@
1
+ require "remote_http_testing/version"
2
+ require "cgi"
3
+ require "nokogiri"
4
+ require "json"
5
+
6
+ #
7
+ # This module helps write integration tests which make HTTP requests to remote servers. Unlike Rack::Test,
8
+ # it doesn't make requests to an in-process Rack server. Include it into your test case class.
9
+ #
10
+ # This module's API should match the API of Rack::Test. In the future, we should consider whether it's just as
11
+ # easy to amend Rack::Test so that it can make requests to remote servers, since Rack::Test has supoprt for
12
+ # other desirable features.
13
+ #
14
+ module RemoteHttpTesting
15
+ attr_accessor :last_response
16
+ attr_accessor :last_request
17
+ # You can set this to be a Hash, and these HTTP headers will be added to all requests.
18
+ attr_accessor :headers_for_request
19
+
20
+ # Define this method to return the URL of the HTTP server to talk to, e.g. "http://localhost:3000"
21
+ def server() raise "You need to define a server() method." end
22
+
23
+ def dom_response
24
+ @dom_response ||= Nokogiri::HTML(last_response.body)
25
+ end
26
+
27
+ def json_response
28
+ @json_response ||= JSON.parse(last_response.body)
29
+ end
30
+
31
+ # Prints out an error message and exits the program (to avoid running subsequent tests which are just
32
+ # going to fail) if the server is not reachable.
33
+ def ensure_reachable!(server_url, server_display_name = nil)
34
+ unless server_reachable?(server_url)
35
+ failure_message = server_display_name ? "#{server_display_name} at #{server_url}" : server_url
36
+ puts "FAIL: Unable to connect to #{failure_message}"
37
+ exit 1
38
+ end
39
+ end
40
+
41
+ # True if the server is reachable. Fails if the server can't be contacted within 2 seconds.
42
+ def server_reachable?(server_url)
43
+ uri = URI.parse(server_url)
44
+ request = Net::HTTP.new(uri.host, uri.port)
45
+ request.read_timeout = 2
46
+ response = nil
47
+ begin
48
+ response = request.request(create_request(server_url, :get))
49
+ rescue StandardError, Timeout::Error
50
+ end
51
+ !response.nil? && response.code.to_i == 200
52
+ end
53
+
54
+ def delete(url, params = {}, request_body = nil) perform_request(url, :delete, params, request_body) end
55
+ def get(url, params = {}, request_body = nil) perform_request(url, :get, params, request_body) end
56
+ def post(url, params = {}, request_body = nil) perform_request(url, :post, params, request_body) end
57
+ def put(url, params = {}, request_body = nil) perform_request(url, :put, params, request_body) end
58
+ def patch(url, params = {}, request_body = nil) perform_request(url, :patch, params, request_body) end
59
+
60
+ # Used by perform_request. This can be overridden by integration tests to append things to the request,
61
+ # like adding a login cookie.
62
+ def create_request(url, http_method, params = {}, request_body = nil)
63
+ uri = URI.parse(url)
64
+ RemoteHttpTesting::populate_uri_with_querystring(uri, params)
65
+ request_class = case http_method
66
+ when :delete then Net::HTTP::Delete
67
+ when :get then Net::HTTP::Get
68
+ when :post then Net::HTTP::Post
69
+ when :put then Net::HTTP::Put
70
+ when :patch then Net::HTTP::Patch
71
+ end
72
+ request = request_class.new(uri.request_uri)
73
+ request.body = request_body if request_body
74
+ headers_for_request.each { |key, value| request.add_field(key, value) } if headers_for_request
75
+ request
76
+ end
77
+
78
+ def perform_request(url, http_method, params = {}, request_body = nil)
79
+ self.last_response = @dom_response = @json_response = nil
80
+ url = self.server + url
81
+ uri = URI.parse(url)
82
+ self.last_request = create_request(url, http_method, params, request_body)
83
+ response = Net::HTTP.new(uri.host, uri.port).request(self.last_request) rescue nil
84
+ raise "Unable to connect to #{self.server}" if response.nil?
85
+ self.last_response = response
86
+ end
87
+
88
+ def self.populate_uri_with_querystring(uri, query_string_hash)
89
+ return if query_string_hash.nil? || query_string_hash == ""
90
+ key_values = query_string_hash.map { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
91
+ uri.query = uri.query.to_s.empty? ? key_values : "&" + key_values # uri.query can be nil
92
+ end
93
+
94
+ def assert_status(status_code, helpful_message = last_response.body)
95
+ assert_equal(status_code.to_i, last_response.code.to_i, helpful_message)
96
+ end
97
+
98
+ def assert_content_include?(string)
99
+ assert_block("Failed: content did not include the string: #{string}") { content_include?(string) }
100
+ end
101
+
102
+ def assert_content_not_include?(string)
103
+ assert_block("Failed: content should not have included this string but it did: #{string}") do
104
+ !content_include?(string)
105
+ end
106
+ end
107
+
108
+ def content_include?(string)
109
+ raise "No request was made yet, or no response was returned" unless last_response
110
+ last_response.body.include?(string)
111
+ end
112
+
113
+ # This is intended to provide similar functionality to the Rails assert_select helper.
114
+ # With no additional options, "assert_select('my_selector')" just ensures there's an element matching the
115
+ # given selector, assuming the response is structured like XML.
116
+ def assert_select(css_selector, options = {})
117
+ raise "You're trying to assert_select when there hasn't been a response yet." unless dom_response
118
+ assert_block("There were no elements matching #{css_selector}") do
119
+ !dom_response.css(css_selector).empty?
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,3 @@
1
+ module RemoteHttpTesting
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # We created this project by running "bundle gem remote_http_testing".
4
+ #
5
+ $:.push File.expand_path("../lib", __FILE__)
6
+ require "remote_http_testing/version"
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = "remote_http_testing"
10
+ s.version = RemoteHttpTesting::VERSION
11
+ s.authors = ["Phil Crosby"]
12
+ s.email = ["phil.crosby@gmail.com"]
13
+ s.homepage = "http://github.com/ooyala"
14
+ s.summary = %q{A small library for making remote HTTP requests and response assertions in tests.}
15
+
16
+ s.rubyforge_project = "remote_http_testing"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_runtime_dependency "nokogiri"
24
+ s.add_runtime_dependency "json"
25
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remote_http_testing
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Phil Crosby
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-02-07 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: nokogiri
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ description:
50
+ email:
51
+ - phil.crosby@gmail.com
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - .gitignore
60
+ - Gemfile
61
+ - README.markdown
62
+ - Rakefile
63
+ - lib/remote_http_testing.rb
64
+ - lib/remote_http_testing/version.rb
65
+ - remote_http_testing.gemspec
66
+ has_rdoc: true
67
+ homepage: http://github.com/ooyala
68
+ licenses: []
69
+
70
+ post_install_message:
71
+ rdoc_options: []
72
+
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ hash: 3
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ requirements: []
94
+
95
+ rubyforge_project: remote_http_testing
96
+ rubygems_version: 1.6.2
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: A small library for making remote HTTP requests and response assertions in tests.
100
+ test_files: []
101
+