forked from ooyala/remote_http_testing
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Include the initial version of the RemoteHttpTesting module.
- Loading branch information
Showing
1 changed file
with
112 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,116 @@ | ||
require "remote_http_testing/version" | ||
require "cgi" | ||
require "nokogiri" | ||
require "json" | ||
|
||
# | ||
# Helpers for writing integration tests which make HTTP requests to the servers being tested. | ||
# Include this module into your test case class. | ||
# | ||
module RemoteHttpTesting | ||
# Your code goes here... | ||
attr_accessor :last_response | ||
attr_accessor :last_request | ||
# You can set this to be a Hash, and these HTTP headers will be added to all requests. | ||
attr_accessor :headers_for_request | ||
|
||
# Define this method to return the URL of the HTTP server to talk to, e.g. "http://localhost:3000" | ||
def server() raise "You need to define a server() method." end | ||
|
||
def dom_response | ||
@dom_response ||= Nokogiri::HTML(last_response.body) | ||
end | ||
|
||
def json_response | ||
@json_response ||= JSON.parse(last_response.body) | ||
end | ||
|
||
def assert_status(status_code, helpful_message = last_response.body) | ||
assert_equal(status_code.to_i, last_response.code.to_i, helpful_message) | ||
end | ||
|
||
def assert_content_include?(string) | ||
assert_block("Failed: content did not include the string: #{string}") { content_include?(string) } | ||
end | ||
|
||
def assert_content_not_include?(string) | ||
assert_block("Failed: should not have included this string but it did: #{string}") do | ||
!content_include?(string) | ||
end | ||
end | ||
|
||
def content_include?(string) | ||
raise "No request was made yet, or no response was returned" unless last_response | ||
last_response.body.include?(string) | ||
end | ||
|
||
# Prints out an error message and exits the program (to avoid running subsequent tests which are just | ||
# going to fail) if the server is not reachable. | ||
def ensure_reachable!(server_url, server_display_name) | ||
unless server_reachable?(server_url) | ||
puts "FAIL: Unable to connect to #{server_display_name} at #{server_url} " | ||
exit 1 | ||
end | ||
end | ||
|
||
# True if the server is reachable. Fails if the server can't be contacted within 2 seconds. | ||
def server_reachable?(server_url) | ||
uri = URI.parse(server_url) | ||
request = Net::HTTP.new(uri.host, uri.port) | ||
request.read_timeout = 2 | ||
response = nil | ||
begin | ||
response = request.request(create_request(server_url, :get)) | ||
rescue StandardError, Timeout::Error | ||
end | ||
!response.nil? && response.code.to_i == 200 | ||
end | ||
|
||
def delete(url, params = {}, request_body = nil) perform_request(url, :delete, params, request_body) end | ||
def get(url, params = {}, request_body = nil) perform_request(url, :get, params, request_body) end | ||
def post(url, params = {}, request_body = nil) perform_request(url, :post, params, request_body) end | ||
def put(url, params = {}, request_body = nil) perform_request(url, :put, params, request_body) end | ||
def patch(url, params = {}, request_body = nil) perform_request(url, :patch, params, request_body) end | ||
|
||
# Used by perform_request. This can be overridden by integration tests to append things to the request, | ||
# like adding a login cookie. | ||
def create_request(url, http_method, params = {}, request_body = nil) | ||
uri = URI.parse(url) | ||
HttpTestingHelper::populate_uri_with_querystring(uri, params) | ||
request = case http_method | ||
when :delete: Net::HTTP::Delete.new(uri.request_uri) | ||
when :get: Net::HTTP::Get.new(uri.request_uri) | ||
when :post: Net::HTTP::Post.new(uri.request_uri) | ||
when :put: Net::HTTP::Put.new(uri.request_uri) | ||
when :patch: Net::HTTP::Patch.new(uri.request_uri) | ||
end | ||
request.body = request_body if request_body | ||
headers_for_request.each { |key, value| request.add_field(key, value) } if headers_for_request | ||
request | ||
end | ||
|
||
def perform_request(url, http_method, params = {}, request_body = nil) | ||
self.last_response = @dom_response = @json_response = nil | ||
url = self.server + url | ||
uri = URI.parse(url) | ||
self.last_request = create_request(url, http_method, params, request_body) | ||
response = Net::HTTP.new(uri.host, uri.port).request(self.last_request) rescue nil | ||
raise "Unable to connect to #{self.server}" if response.nil? | ||
self.last_response = response | ||
end | ||
|
||
def self.populate_uri_with_querystring(uri, query_string_hash) | ||
return if query_string_hash.nil? || query_string_hash == "" | ||
key_values = query_string_hash.map { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&") | ||
uri.query = uri.query.to_s.empty? ? key_values : "&" + key_values # uri.query can be nil | ||
end | ||
|
||
# This is intended to provide similar functionality to the Rails assert_select helper. | ||
# With no additional options, "assert_select('my_selector')" just ensures there's an element matching the | ||
# given selector, assuming the response is structured like XML. | ||
def assert_select(css_selector, options = {}) | ||
raise "You're trying to assert_select when there hasn't been a response yet." unless dom_response | ||
assert_block("There were no elements matching #{css_selector}") do | ||
!dom_response.css(css_selector).empty? | ||
end | ||
end | ||
end |