aitch 0.5.0 → 1.0.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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -5
- data/CHANGELOG.md +38 -0
- data/README.md +50 -14
- data/Rakefile +10 -0
- data/aitch.gemspec +4 -2
- data/lib/aitch.rb +7 -2
- data/lib/aitch/configuration.rb +1 -12
- data/lib/aitch/dsl.rb +1 -0
- data/lib/aitch/errors.rb +1 -0
- data/lib/aitch/ext/to_query.rb +1 -0
- data/lib/aitch/location.rb +3 -2
- data/lib/aitch/namespace.rb +1 -0
- data/lib/aitch/redirect.rb +8 -2
- data/lib/aitch/request.rb +22 -9
- data/lib/aitch/response.rb +4 -13
- data/lib/aitch/response/body.rb +1 -0
- data/lib/aitch/response/description.rb +52 -51
- data/lib/aitch/response/errors.rb +1 -0
- data/lib/aitch/response_parser.rb +29 -0
- data/lib/aitch/response_parser/default_parser.rb +18 -0
- data/lib/aitch/response_parser/html_parser.rb +18 -0
- data/lib/aitch/response_parser/json_parser.rb +18 -0
- data/lib/aitch/response_parser/xml_parser.rb +18 -0
- data/lib/aitch/uri.rb +1 -0
- data/lib/aitch/utils.rb +1 -0
- data/lib/aitch/version.rb +2 -1
- data/test/aitch/aitch_test.rb +27 -0
- data/test/aitch/configuration_test.rb +29 -0
- data/test/aitch/dsl_test.rb +48 -0
- data/test/aitch/execute_test.rb +45 -0
- data/test/aitch/namespace_test.rb +12 -0
- data/test/aitch/request/client_https_test.rb +20 -0
- data/test/aitch/request/follow_redirect_test.rb +64 -0
- data/test/aitch/request/request_class_test.rb +28 -0
- data/test/aitch/request/status_code_validation_test.rb +19 -0
- data/test/aitch/request_test.rb +138 -0
- data/test/aitch/response/custom_response_parser_test.rb +31 -0
- data/test/aitch/response/errors_test.rb +16 -0
- data/test/aitch/response/html_response_test.rb +18 -0
- data/test/aitch/response/json_response_test.rb +18 -0
- data/test/aitch/response/raw_response_test.rb +11 -0
- data/test/aitch/response/status_3xx_test.rb +56 -0
- data/test/aitch/response/status_4xx_test.rb +18 -0
- data/test/aitch/response/status_5xx_test.rb +18 -0
- data/test/aitch/response/xml_response_test.rb +18 -0
- data/test/aitch/response_parser/html_parser_test.rb +9 -0
- data/test/aitch/response_parser/json_parser_test.rb +9 -0
- data/test/aitch/response_parser/xml_parser_test.rb +17 -0
- data/test/aitch/response_test.rb +114 -0
- data/test/aitch/uri_test.rb +37 -0
- data/test/aitch/utils/symbolize_keys_test.rb +9 -0
- data/test/aitch/utils/underscore_test.rb +12 -0
- data/{spec → test}/fixtures/iso8859-1.xml +0 -0
- data/{spec/support/request_uri.rb → test/support/helpers.rb} +12 -3
- data/test/test_helper.rb +15 -0
- metadata +70 -37
- data/.rspec +0 -1
- data/lib/aitch/html_parser.rb +0 -7
- data/lib/aitch/xml_parser.rb +0 -7
- data/spec/aitch/aitch_spec.rb +0 -71
- data/spec/aitch/configuration_spec.rb +0 -33
- data/spec/aitch/dsl_spec.rb +0 -47
- data/spec/aitch/html_parser_spec.rb +0 -8
- data/spec/aitch/namespace_spec.rb +0 -11
- data/spec/aitch/request_spec.rb +0 -261
- data/spec/aitch/response_spec.rb +0 -259
- data/spec/aitch/uri_spec.rb +0 -36
- data/spec/aitch/utils_spec.rb +0 -19
- data/spec/aitch/xml_parser_spec.rb +0 -16
- data/spec/spec_helper.rb +0 -24
- data/spec/support/webmock.rb +0 -15
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
require "csv"
|
4
|
+
|
5
|
+
class CustomResponseParserTest < Minitest::Test
|
6
|
+
setup do
|
7
|
+
parser = Class.new do
|
8
|
+
def self.type
|
9
|
+
:csv
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.match?(content_type)
|
13
|
+
content_type =~ /csv/
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.load(source)
|
17
|
+
CSV.parse(source)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Aitch::ResponseParser.prepend(:csv, parser)
|
22
|
+
end
|
23
|
+
|
24
|
+
test "returns csv" do
|
25
|
+
register_uri(:get, "http://example.org/file.csv", body: "1,2,3", content_type: "text/csv")
|
26
|
+
response = Aitch.get("http://example.org/file.csv")
|
27
|
+
|
28
|
+
assert_instance_of Array, response.data
|
29
|
+
assert_equal [%w[1 2 3]], response.data
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class ErrorsTest < Minitest::Test
|
5
|
+
Aitch::Response::ERRORS.each do |code, exception|
|
6
|
+
name = Aitch::Utils.underscore(exception.name.split("::").last).gsub("_error", "")
|
7
|
+
|
8
|
+
test "detects response as #{name}" do
|
9
|
+
config = {}
|
10
|
+
http_response = stub(code: code)
|
11
|
+
response = Aitch::Response.new(config, http_response)
|
12
|
+
|
13
|
+
assert response.public_send("#{name}?")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class HtmlResponseTest < Minitest::Test
|
5
|
+
test "detects as html" do
|
6
|
+
register_uri(:get, "http://example.org/", body: "", content_type: "text/html")
|
7
|
+
response = Aitch.get("http://example.org/")
|
8
|
+
|
9
|
+
assert response.html?
|
10
|
+
end
|
11
|
+
|
12
|
+
test "returns html" do
|
13
|
+
register_uri(:get, "http://example.org/", body: "Hello", content_type: "text/html")
|
14
|
+
response = Aitch.get("http://example.org/")
|
15
|
+
|
16
|
+
assert_instance_of Nokogiri::HTML::Document, response.data
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class JsonResponseTest < Minitest::Test
|
5
|
+
test "detects as json" do
|
6
|
+
register_uri(:get, "http://example.org/", body: "[]", content_type: "application/json")
|
7
|
+
response = Aitch.get("http://example.org/")
|
8
|
+
|
9
|
+
assert response.json?
|
10
|
+
end
|
11
|
+
|
12
|
+
test "returns json" do
|
13
|
+
register_uri(:get, "http://example.org/", body: "[1,2,3]", content_type: "application/json")
|
14
|
+
response = Aitch.get("http://example.org/")
|
15
|
+
|
16
|
+
assert_equal [1,2,3], response.data
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class RawResponseTest < Minitest::Test
|
5
|
+
test "returns body as it is (raw)" do
|
6
|
+
register_uri(:get, "http://example.org/", body: "HELLO", content_type: "text/plain")
|
7
|
+
response = Aitch.get("http://example.org/")
|
8
|
+
|
9
|
+
assert_equal "HELLO", response.body
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class Status3xxTest < Minitest::Test
|
5
|
+
setup { Aitch.configuration.follow_redirect = false }
|
6
|
+
|
7
|
+
test "sets default redirected from" do
|
8
|
+
assert_equal [], Aitch::Response.new({}, stub("response")).redirected_from
|
9
|
+
end
|
10
|
+
|
11
|
+
test "uses provided redirected from" do
|
12
|
+
assert_equal ["URL"], Aitch::Response.new({redirected_from: ["URL"]}, stub("response")).redirected_from
|
13
|
+
end
|
14
|
+
|
15
|
+
test "has body" do
|
16
|
+
register_uri(:get, "http://example.org/", body: "Hello", status: 301)
|
17
|
+
response = Aitch.get("http://example.org/")
|
18
|
+
assert_equal "Hello", response.body
|
19
|
+
end
|
20
|
+
|
21
|
+
test "detects as successful response" do
|
22
|
+
register_uri(:get, "http://example.org/", status: 301)
|
23
|
+
response = Aitch.get("http://example.org/")
|
24
|
+
|
25
|
+
assert response.success?
|
26
|
+
assert response.ok?
|
27
|
+
end
|
28
|
+
|
29
|
+
test "detects as redirect" do
|
30
|
+
register_uri(:get, "http://example.org/", status: 301)
|
31
|
+
response = Aitch.get("http://example.org/")
|
32
|
+
|
33
|
+
assert response.redirect?
|
34
|
+
end
|
35
|
+
|
36
|
+
test "returns location" do
|
37
|
+
register_uri(:get, "http://example.org/", status: 301, location: "https://example.com/")
|
38
|
+
response = Aitch.get("http://example.org/")
|
39
|
+
assert_equal "https://example.com/", response.location
|
40
|
+
end
|
41
|
+
|
42
|
+
test "follows absolute paths" do
|
43
|
+
Aitch.configuration.follow_redirect = true
|
44
|
+
Aitch.configuration.redirect_limit = 5
|
45
|
+
|
46
|
+
register_uri(:get, "http://example.org/", status: 301, location: "/hello")
|
47
|
+
register_uri(:get, "http://example.org/hello", status: 301, location: "/hi")
|
48
|
+
register_uri(:get, "http://example.org/hi", status: 200, body: "Hi")
|
49
|
+
|
50
|
+
response = Aitch.get("http://example.org/")
|
51
|
+
|
52
|
+
assert_equal ["http://example.org/", "http://example.org/hello"], response.redirected_from
|
53
|
+
assert_equal "http://example.org/hi", response.url
|
54
|
+
assert_equal "Hi", response.body
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class Status4xxTest < Minitest::Test
|
5
|
+
test "detects as error" do
|
6
|
+
register_uri(:get, "http://example.org/", status: 404)
|
7
|
+
response = Aitch.get("http://example.org/")
|
8
|
+
|
9
|
+
assert response.error?
|
10
|
+
end
|
11
|
+
|
12
|
+
test "sets error" do
|
13
|
+
register_uri(:get, "http://example.org/", status: 404)
|
14
|
+
response = Aitch.get("http://example.org/")
|
15
|
+
|
16
|
+
assert_equal Aitch::NotFoundError, response.error
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class Status5xxTest < Minitest::Test
|
5
|
+
test "detects as error" do
|
6
|
+
register_uri(:get, "http://example.org/", status: 500)
|
7
|
+
response = Aitch.get("http://example.org/")
|
8
|
+
|
9
|
+
assert response.error?
|
10
|
+
end
|
11
|
+
|
12
|
+
test "sets error" do
|
13
|
+
register_uri(:get, "http://example.org/", status: 500)
|
14
|
+
response = Aitch.get("http://example.org/")
|
15
|
+
|
16
|
+
assert_equal Aitch::InternalServerErrorError, response.error
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class XmlResponseTest < Minitest::Test
|
5
|
+
test "detects as xml" do
|
6
|
+
register_uri(:get, "http://example.org/", body: "[]", content_type: "application/xml")
|
7
|
+
response = Aitch.get("http://example.org/")
|
8
|
+
|
9
|
+
assert response.xml?
|
10
|
+
end
|
11
|
+
|
12
|
+
test "returns xml" do
|
13
|
+
register_uri(:get, "http://example.org/", body: "<foo/>", content_type: "application/xml")
|
14
|
+
response = Aitch.get("http://example.org/")
|
15
|
+
|
16
|
+
assert_instance_of Nokogiri::XML::Document, response.data
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class XmlParserTest < Minitest::Test
|
6
|
+
test "instantiates Nokogiri" do
|
7
|
+
Nokogiri.expects(:XML).with("XML", nil, "utf-8")
|
8
|
+
Aitch::ResponseParser::XMLParser.load("XML")
|
9
|
+
end
|
10
|
+
|
11
|
+
test "converts ISO-8859-1 to UTF-8" do
|
12
|
+
xml = Aitch::ResponseParser::XMLParser.load(File.read("./test/fixtures/iso8859-1.xml"))
|
13
|
+
|
14
|
+
assert_equal "utf-8", xml.encoding
|
15
|
+
assert_includes xml.to_xml, %[<?xml version="1.0" encoding="utf-8"?>]
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class ResponseTest < Minitest::Test
|
5
|
+
test "has body" do
|
6
|
+
register_uri(:get, "http://example.org/", body: "Hello")
|
7
|
+
response = Aitch.get("http://example.org/")
|
8
|
+
assert_equal "Hello", response.body
|
9
|
+
end
|
10
|
+
|
11
|
+
test "sets current url" do
|
12
|
+
register_uri(:get, "http://example.org/", body: "Hello")
|
13
|
+
response = Aitch.get("http://example.org/")
|
14
|
+
assert_equal "http://example.org/", response.url
|
15
|
+
end
|
16
|
+
|
17
|
+
test "parses gzip response" do
|
18
|
+
stdio = StringIO.new
|
19
|
+
gzipped = Zlib::GzipWriter.new(stdio)
|
20
|
+
gzipped.write("Hello")
|
21
|
+
gzipped.finish
|
22
|
+
|
23
|
+
register_uri(:get, "http://example.org/", body: stdio.string, content_encoding: "gzip")
|
24
|
+
response = Aitch.get("http://example.org/")
|
25
|
+
|
26
|
+
assert_equal "Hello", response.body
|
27
|
+
end
|
28
|
+
|
29
|
+
test "deflates response" do
|
30
|
+
stdio = StringIO.new
|
31
|
+
deflated = Zlib::Deflate.deflate("Hello")
|
32
|
+
|
33
|
+
register_uri(:get, "http://example.org/", body: deflated, content_encoding: "deflate")
|
34
|
+
response = Aitch.get("http://example.org/")
|
35
|
+
|
36
|
+
assert_equal "Hello", response.body
|
37
|
+
end
|
38
|
+
|
39
|
+
test "returns status code" do
|
40
|
+
register_uri(:get, "http://example.org/", body: "")
|
41
|
+
response = Aitch.get("http://example.org/")
|
42
|
+
assert_equal 200, response.code
|
43
|
+
end
|
44
|
+
|
45
|
+
test "returns content type" do
|
46
|
+
register_uri(:get, "http://example.org/", content_type: "text/html")
|
47
|
+
response = Aitch.get("http://example.org/")
|
48
|
+
assert_equal "text/html", response.content_type
|
49
|
+
end
|
50
|
+
|
51
|
+
test "detects as successful response" do
|
52
|
+
register_uri(:get, "http://example.org/", content_type: "text/html")
|
53
|
+
response = Aitch.get("http://example.org/")
|
54
|
+
assert response.success?
|
55
|
+
end
|
56
|
+
|
57
|
+
test "returns headers" do
|
58
|
+
register_uri(:get, "http://example.org/", content_type: "text/html")
|
59
|
+
headers = Aitch.get("http://example.org/").headers
|
60
|
+
|
61
|
+
assert_instance_of Hash, headers
|
62
|
+
assert_equal "text/html", headers["content-type"]
|
63
|
+
end
|
64
|
+
|
65
|
+
test "normalizes custom headers" do
|
66
|
+
register_uri(:get, "http://example.org/", headers: {"X-Runtime" => "0.003"})
|
67
|
+
headers = Aitch.get("http://example.org/").headers
|
68
|
+
|
69
|
+
assert_equal "0.003", headers["runtime"]
|
70
|
+
end
|
71
|
+
|
72
|
+
test "maps missing methods to headers" do
|
73
|
+
register_uri(:get, "http://example.org/", headers: {"X-Runtime" => "0.003"})
|
74
|
+
response = Aitch.get("http://example.org/")
|
75
|
+
|
76
|
+
assert_equal "0.003", response.runtime
|
77
|
+
assert response.respond_to?(:runtime)
|
78
|
+
end
|
79
|
+
|
80
|
+
test "raises when have no method" do
|
81
|
+
register_uri(:get, "http://example.org/")
|
82
|
+
response = Aitch.get("http://example.org/")
|
83
|
+
|
84
|
+
assert_raises(NoMethodError) { response.runtime }
|
85
|
+
end
|
86
|
+
|
87
|
+
test "returns description for 200 OK" do
|
88
|
+
register_uri(:get, "http://example.org/", status: 200)
|
89
|
+
response = Aitch.get("http://example.org/")
|
90
|
+
|
91
|
+
assert_equal "200 OK", response.description
|
92
|
+
end
|
93
|
+
|
94
|
+
test "returns description for 101 Switch Protocol" do
|
95
|
+
register_uri(:get, "http://example.org/", status: 101)
|
96
|
+
response = Aitch.get("http://example.org/")
|
97
|
+
|
98
|
+
assert_equal "101 Switch Protocol", response.description
|
99
|
+
end
|
100
|
+
|
101
|
+
test "returns description for 444 No Response (nginx)" do
|
102
|
+
register_uri(:get, "http://example.org/", status: 444)
|
103
|
+
response = Aitch.get("http://example.org/")
|
104
|
+
|
105
|
+
assert_equal "444", response.description
|
106
|
+
end
|
107
|
+
|
108
|
+
test "overrides inspect" do
|
109
|
+
register_uri(:get, "http://example.org/", status: 101, content_type: "text/html")
|
110
|
+
response = Aitch.get("http://example.org/")
|
111
|
+
|
112
|
+
assert_equal "#<Aitch::Response 101 Switch Protocol (text/html)>", response.inspect
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class UriTest < Minitest::Test
|
5
|
+
test "returns default path" do
|
6
|
+
assert_equal "/", Aitch::URI.new("http://example.org").path
|
7
|
+
end
|
8
|
+
|
9
|
+
test "returns defined path" do
|
10
|
+
assert_equal "/some/path", Aitch::URI.new("http://example.org/some/path").path
|
11
|
+
end
|
12
|
+
|
13
|
+
test "returns fragment" do
|
14
|
+
assert_equal "#top", Aitch::URI.new("http://example.org/#top").fragment
|
15
|
+
end
|
16
|
+
|
17
|
+
test "returns query string" do
|
18
|
+
assert_equal "?a=1&b=2", Aitch::URI.new("http://example.org/?a=1&b=2").query
|
19
|
+
end
|
20
|
+
|
21
|
+
test "converts data into query string" do
|
22
|
+
assert_equal "?a=1&b=2", Aitch::URI.new("http://example.org", a: 1, b: 2).query
|
23
|
+
end
|
24
|
+
|
25
|
+
test "merges data into query string" do
|
26
|
+
assert_equal "?a=1&b=2&c=3", Aitch::URI.new("http://example.org/?a=1&b=2", c: 3).query
|
27
|
+
end
|
28
|
+
|
29
|
+
test "ignores data when request has body" do
|
30
|
+
assert_equal nil, Aitch::URI.new("http://example.org/", {c: 3}, true).query
|
31
|
+
end
|
32
|
+
|
33
|
+
test "returns request uri" do
|
34
|
+
uri = Aitch::URI.new("http://example.org/some/path?a=1&b=2#hello", c: 3)
|
35
|
+
assert_equal "/some/path?a=1&b=2&c=3#hello", uri.request_uri
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class UnderscoreTest < Minitest::Test
|
5
|
+
test "replaces capital letters by underscores" do
|
6
|
+
assert_equal "some_constant_name", Aitch::Utils.underscore("SomeConstantName")
|
7
|
+
end
|
8
|
+
|
9
|
+
test "considers URI acronym" do
|
10
|
+
assert_equal "request_uri_too_long", Aitch::Utils.underscore("RequestURITooLong")
|
11
|
+
end
|
12
|
+
end
|
File without changes
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Minitest
|
3
|
+
class Test
|
3
4
|
def add_hash_entry(source, target, from, to)
|
4
5
|
target[to] = source[from] if source[from]
|
5
6
|
end
|
@@ -20,5 +21,13 @@ RSpec.configure do |config|
|
|
20
21
|
def last_request
|
21
22
|
WebMock.requests.last
|
22
23
|
end
|
23
|
-
|
24
|
+
|
25
|
+
def build_request(options = {})
|
26
|
+
Aitch::Request.new({
|
27
|
+
request_method: "get",
|
28
|
+
url: "http://example.org",
|
29
|
+
options: {}
|
30
|
+
}.merge(options))
|
31
|
+
end
|
32
|
+
end
|
24
33
|
end
|