remote_http_testing 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+