hover-ruby-client 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +30 -0
- data/.gitignore +64 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +161 -0
- data/README.md +50 -0
- data/Rakefile +14 -0
- data/hover-ruby-client.gemspec +38 -0
- data/lib/hover/client/basic_auth.rb +18 -0
- data/lib/hover/client/hmac.rb +20 -0
- data/lib/hover/client/hover.rb +29 -0
- data/lib/hover/client/http.rb +141 -0
- data/lib/hover/client/manowar.rb +17 -0
- data/lib/hover/client/midas.rb +120 -0
- data/lib/hover/client/static.rb +89 -0
- data/lib/hover/decoder/json_stream.rb +25 -0
- data/lib/hover/encoder/json_stream.rb +35 -0
- data/lib/hover/importer/active_record.rb +134 -0
- data/lib/hover/jobs/concerns/retry_network_errors.rb +45 -0
- data/lib/hover/version.rb +3 -0
- data/test/app/Gemfile +1 -0
- data/test/files/archive.zip +0 -0
- data/test/files/encoded.json +106 -0
- data/test/test_helper.rb +80 -0
- data/test/unit/client/basic_auth_test.rb +21 -0
- data/test/unit/client/hmac_test.rb +277 -0
- data/test/unit/client/hover_test.rb +62 -0
- data/test/unit/client/manowar_test.rb +34 -0
- data/test/unit/client/midas_test.rb +187 -0
- data/test/unit/client/static_test.rb +169 -0
- data/test/unit/decoder/json_stream_test.rb +8 -0
- data/test/unit/encoder/json_stream_test.rb +135 -0
- data/test/unit/importer/active_record_test.rb +354 -0
- data/test/unit/jobs/concerns/retry_network_errors_test.rb +23 -0
- metadata +286 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'hover/client/hover'
|
3
|
+
|
4
|
+
module Hover
|
5
|
+
module Jobs
|
6
|
+
module Concerns
|
7
|
+
module RetryNetworkErrors
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
@backoff_strategy = [1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60, 120, 240, 480]
|
12
|
+
|
13
|
+
# http://ruby-doc.org/stdlib-1.9.2/libdoc/socket/rdoc/Socket.html
|
14
|
+
|
15
|
+
@retry_exceptions = [
|
16
|
+
Hover::Client::Unavailable,
|
17
|
+
Timeout::Error,
|
18
|
+
Net::ProtocolError,
|
19
|
+
Errno::ECONNRESET,
|
20
|
+
Errno::ECONNREFUSED,
|
21
|
+
Errno::EALREADY,
|
22
|
+
Errno::EFAULT,
|
23
|
+
Errno::EHOSTUNREACH,
|
24
|
+
Errno::EINPROGRESS,
|
25
|
+
Errno::EINTR,
|
26
|
+
Errno::EISCONN,
|
27
|
+
Errno::EINVAL,
|
28
|
+
Errno::ENETDOWN,
|
29
|
+
Errno::ENETUNREACH,
|
30
|
+
Errno::ENOBUFS,
|
31
|
+
Errno::ENOSR,
|
32
|
+
Errno::EOPNOTSUPP,
|
33
|
+
Errno::ETIMEDOUT
|
34
|
+
]
|
35
|
+
|
36
|
+
#
|
37
|
+
# make sure this comes after the variables above ^
|
38
|
+
#
|
39
|
+
extend Resque::Plugins::ExponentialBackoff if defined?(Resque::Plugins::ExponentialBackoff)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/test/app/Gemfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
source 'https://rubygems.org'
|
Binary file
|
@@ -0,0 +1,106 @@
|
|
1
|
+
{"id":6,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
2
|
+
{"id":7,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
3
|
+
{"id":8,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
4
|
+
{"id":9,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
5
|
+
{"id":10,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
6
|
+
{"id":11,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
7
|
+
{"id":12,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
8
|
+
{"id":13,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
9
|
+
{"id":14,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
10
|
+
{"id":15,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
11
|
+
{"id":16,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
12
|
+
{"id":17,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
13
|
+
{"id":18,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
14
|
+
{"id":19,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
15
|
+
{"id":20,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
16
|
+
{"id":21,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
17
|
+
{"id":22,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
18
|
+
{"id":23,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
19
|
+
{"id":24,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
20
|
+
{"id":25,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
21
|
+
{"id":26,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
22
|
+
{"id":27,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
23
|
+
{"id":28,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
24
|
+
{"id":29,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
25
|
+
{"id":30,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
26
|
+
{"id":31,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
27
|
+
{"id":32,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
28
|
+
{"id":33,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
29
|
+
{"id":34,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
30
|
+
{"id":35,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
31
|
+
{"id":36,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
32
|
+
{"id":37,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
33
|
+
{"id":38,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
34
|
+
{"id":39,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
35
|
+
{"id":40,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
36
|
+
{"id":41,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
37
|
+
{"id":42,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
38
|
+
{"id":43,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
39
|
+
{"id":44,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
40
|
+
{"id":45,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
41
|
+
{"id":46,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
42
|
+
{"id":47,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
43
|
+
{"id":48,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
44
|
+
{"id":49,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
45
|
+
{"id":50,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
46
|
+
{"id":51,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
47
|
+
{"id":52,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
48
|
+
{"id":53,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
49
|
+
{"id":54,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
50
|
+
{"id":55,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
51
|
+
{"id":56,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
52
|
+
{"id":57,"image":null,"item_id":null,"a":null,"class":"TestClass"}
|
53
|
+
{"id":1,"taggable_id":1,"taggable_type":"Item","name":"tag","class":"Tag"}
|
54
|
+
{"id":2,"taggable_id":1,"taggable_type":"Item","name":"tag","class":"Tag"}
|
55
|
+
{"id":3,"taggable_id":1,"taggable_type":"Item","name":"tag","class":"Tag"}
|
56
|
+
{"id":4,"taggable_id":2,"taggable_type":"Item","name":"tag","class":"Tag"}
|
57
|
+
{"id":5,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
58
|
+
{"id":6,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
59
|
+
{"id":7,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
60
|
+
{"id":8,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
61
|
+
{"id":9,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
62
|
+
{"id":10,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
63
|
+
{"id":11,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
64
|
+
{"id":12,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
65
|
+
{"id":13,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
66
|
+
{"id":14,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
67
|
+
{"id":15,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
68
|
+
{"id":16,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
69
|
+
{"id":17,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
70
|
+
{"id":18,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
71
|
+
{"id":19,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
72
|
+
{"id":20,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
73
|
+
{"id":21,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
74
|
+
{"id":22,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
75
|
+
{"id":23,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
76
|
+
{"id":24,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
77
|
+
{"id":25,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
78
|
+
{"id":26,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
79
|
+
{"id":27,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
80
|
+
{"id":28,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
81
|
+
{"id":29,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
82
|
+
{"id":30,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
83
|
+
{"id":31,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
84
|
+
{"id":32,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
85
|
+
{"id":33,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
86
|
+
{"id":34,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
87
|
+
{"id":35,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
88
|
+
{"id":36,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
89
|
+
{"id":37,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
90
|
+
{"id":38,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
91
|
+
{"id":39,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
92
|
+
{"id":40,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
93
|
+
{"id":41,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
94
|
+
{"id":42,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
95
|
+
{"id":43,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
96
|
+
{"id":44,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
97
|
+
{"id":45,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
98
|
+
{"id":46,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
99
|
+
{"id":47,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
100
|
+
{"id":48,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
101
|
+
{"id":49,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
102
|
+
{"id":50,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
103
|
+
{"id":51,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
104
|
+
{"id":52,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
105
|
+
{"id":53,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
106
|
+
{"id":54,"taggable_id":null,"taggable_type":null,"name":null,"class":"Tag"}
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
ENV['RAILS_ENV'] ||= 'test'
|
2
|
+
IS_RAKE_TASK = (!! ($0 =~ /rake/))
|
3
|
+
|
4
|
+
if IS_RAKE_TASK
|
5
|
+
#
|
6
|
+
# Code coverage reports
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'coverage'
|
10
|
+
require 'simplecov'
|
11
|
+
require 'simplecov-rcov'
|
12
|
+
|
13
|
+
ROOT_DIR = File.expand_path('../..', __FILE__)
|
14
|
+
|
15
|
+
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
16
|
+
|
17
|
+
SimpleCov.start do
|
18
|
+
minimum_coverage 0
|
19
|
+
coverage_dir File.join(File.dirname(__FILE__), 'reports')
|
20
|
+
root ROOT_DIR
|
21
|
+
|
22
|
+
add_filter do |src|
|
23
|
+
File.dirname(src.filename) =~ /#{File.join(ROOT_DIR, 'test')}/
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
require 'minitest/autorun'
|
29
|
+
require 'minitest/mock'
|
30
|
+
require 'mocha/minitest'
|
31
|
+
require 'minitest/reporters'
|
32
|
+
|
33
|
+
reporters = [ Minitest::Reporters::SpecReporter.new ]
|
34
|
+
|
35
|
+
Minitest::Reporters.use!(reporters)
|
36
|
+
|
37
|
+
|
38
|
+
def index_json_hash(collection, page = 1, per_page = 2)
|
39
|
+
{
|
40
|
+
"pagination" => {
|
41
|
+
"current_page" => page,
|
42
|
+
"total_pages" => (collection.size / per_page),
|
43
|
+
"total" => collection.size,
|
44
|
+
"per_page" => per_page
|
45
|
+
},
|
46
|
+
|
47
|
+
"results" => collection.slice((per_page * (page - 1)), per_page)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
require 'byebug'
|
52
|
+
require 'rails/all'
|
53
|
+
require 'active_record'
|
54
|
+
|
55
|
+
database_path = '/tmp/hover-ruby-client_test.sqlite3'
|
56
|
+
FileUtils.rm(database_path) if File.exist?(database_path)
|
57
|
+
ActiveRecord::Base.establish_connection({adapter: :sqlite3, database: database_path})
|
58
|
+
|
59
|
+
ActiveRecord::Schema.define do
|
60
|
+
create_table(:test_classes) do |t|
|
61
|
+
t.text :image
|
62
|
+
t.text :document
|
63
|
+
t.integer :item_id
|
64
|
+
t.integer :a
|
65
|
+
end
|
66
|
+
|
67
|
+
create_table(:scoped_test_classes) do |t|
|
68
|
+
t.integer :item_id
|
69
|
+
t.integer :a
|
70
|
+
end
|
71
|
+
|
72
|
+
create_table(:items) do |t|
|
73
|
+
end
|
74
|
+
|
75
|
+
create_table(:tags) do |t|
|
76
|
+
t.integer :taggable_id
|
77
|
+
t.string :taggable_type
|
78
|
+
t.string :name
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require './test/test_helper'
|
2
|
+
|
3
|
+
require 'hover/client/basic_auth'
|
4
|
+
|
5
|
+
describe Hover::Client::BasicAuth do
|
6
|
+
let(:client) { Hover::Client::BasicAuth.new('elise@hoverinc.com', 'password') }
|
7
|
+
let(:path) { '/testing' }
|
8
|
+
let(:request) { mock }
|
9
|
+
let(:response) { mock }
|
10
|
+
|
11
|
+
describe "authenticate" do
|
12
|
+
it "authenticate" do
|
13
|
+
request = mock
|
14
|
+
request.expects(:basic_auth).with('elise@hoverinc.com', 'password')
|
15
|
+
|
16
|
+
client.authenticate(request)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,277 @@
|
|
1
|
+
require './test/test_helper'
|
2
|
+
|
3
|
+
require 'hover/client/hmac'
|
4
|
+
|
5
|
+
describe Hover::Client::HMAC do
|
6
|
+
let(:client) { Hover::Client::HMAC.new(1, 2, 'http://localhost') }
|
7
|
+
let(:path) { '/testing' }
|
8
|
+
let(:request) { mock }
|
9
|
+
let(:response) { mock }
|
10
|
+
|
11
|
+
describe "authenticate" do
|
12
|
+
it "authenticate" do
|
13
|
+
request = mock
|
14
|
+
ApiAuth.expects(:sign!).with(request, 1, 2).once
|
15
|
+
|
16
|
+
client.authenticate(request)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "make_uri" do
|
21
|
+
it "makes correct uri with parameters" do
|
22
|
+
client.make_uri('testing', {a: 1}).to_s.must_equal("http://localhost/api/v1/testing?a=1")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "with parameters" do
|
26
|
+
URI.expects(:parse).twice
|
27
|
+
URI.expects(:encode_www_form).with({a: 1}).once
|
28
|
+
|
29
|
+
client.make_uri('testing', {a: 1})
|
30
|
+
end
|
31
|
+
|
32
|
+
it "makes correct uri without parameters" do
|
33
|
+
client.make_uri('testing').to_s.must_equal("http://localhost/api/v1/testing")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "without parameters" do
|
37
|
+
URI.expects(:parse).once
|
38
|
+
Array.any_instance.expects(:join).once.returns('http://localhost/api/v1/testing')
|
39
|
+
URI.expects(:encode_www_form).never
|
40
|
+
|
41
|
+
client.make_uri('testing')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "make_request" do
|
46
|
+
it "requests without ssl" do
|
47
|
+
uri = URI('http://localhost/test')
|
48
|
+
http = mock
|
49
|
+
|
50
|
+
http.expects(:request).with(request).returns(response).once
|
51
|
+
http.expects(:use_ssl=).never
|
52
|
+
|
53
|
+
client.expects(:raise_errors_for_cloudfront_response)
|
54
|
+
client.expects(:authenticate).with(request).once
|
55
|
+
Net::HTTP.expects(:new).with(uri.host, uri.port).returns(http)
|
56
|
+
|
57
|
+
client.make_request(request, uri).must_equal(response)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'requests with ssl' do
|
61
|
+
uri = URI('https://localhost/test')
|
62
|
+
http = mock
|
63
|
+
|
64
|
+
http.expects(:request).with(request).returns(response).once
|
65
|
+
http.expects(:use_ssl=).with(true).once
|
66
|
+
|
67
|
+
client.expects(:raise_errors_for_cloudfront_response)
|
68
|
+
client.expects(:authenticate).with(request).once
|
69
|
+
Net::HTTP.expects(:new).with(uri.host, uri.port).returns(http)
|
70
|
+
|
71
|
+
client.make_request(request, uri).must_equal(response)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "get" do
|
76
|
+
it "gets without parameters" do
|
77
|
+
uri = URI("http://localhost/testing")
|
78
|
+
Net::HTTP::Get.expects(:new).with(uri).returns(request)
|
79
|
+
client.expects(:make_request).with(request, uri).returns(response)
|
80
|
+
|
81
|
+
client.expects(:make_uri).with(path, {}).once.returns(uri)
|
82
|
+
|
83
|
+
client.get(path)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "gets with parameters" do
|
87
|
+
parameters = {a: 1, b: 2}
|
88
|
+
uri = URI("http://localhost/testing?a=1&b=2")
|
89
|
+
Net::HTTP::Get.expects(:new).with(uri).returns(request)
|
90
|
+
client.expects(:make_request).with(request, uri).returns(response)
|
91
|
+
|
92
|
+
client.expects(:make_uri).with(path, parameters).once.returns(uri)
|
93
|
+
|
94
|
+
client.get(path, parameters)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "get_redirect_location" do
|
99
|
+
let(:uri) { URI("http://localhost/testing") }
|
100
|
+
|
101
|
+
before do
|
102
|
+
client.expects(:parse_response).never
|
103
|
+
|
104
|
+
Net::HTTP::Get.expects(:new).with(uri).returns(request)
|
105
|
+
client.expects(:make_request).with(request, uri).returns(response)
|
106
|
+
client.expects(:make_uri).with(path, {}).once.returns(uri)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "isn't a redirect response" do
|
110
|
+
response.expects(:is_a?).with(Net::HTTPRedirection).returns(false)
|
111
|
+
response.expects(:[]).with('location').never
|
112
|
+
|
113
|
+
assert_nil client.get_redirect_location(path)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "is a redirect response, but no location was given" do
|
117
|
+
response.expects(:is_a?).with(Net::HTTPRedirection).returns(true)
|
118
|
+
response.expects(:[]).with('location').once.returns(nil)
|
119
|
+
|
120
|
+
assert_nil client.get_redirect_location(path)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "is a redirect" do
|
124
|
+
redirect_location = 'http://location/elsewhere'
|
125
|
+
|
126
|
+
response.expects(:is_a?).with(Net::HTTPRedirection).returns(true)
|
127
|
+
response.expects(:[]).with('location').returns(redirect_location).twice
|
128
|
+
|
129
|
+
client.get_redirect_location(path).must_equal(redirect_location)
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "post" do
|
135
|
+
it 'posts' do
|
136
|
+
path = '/post'
|
137
|
+
uri = URI.parse('http://localhost/post')
|
138
|
+
|
139
|
+
client.expects(:make_uri).with(path).returns(uri).once
|
140
|
+
Net::HTTP::Post.expects(:new).with(uri).returns(request)
|
141
|
+
|
142
|
+
client.expects(:make_request).with(request, uri).returns(response)
|
143
|
+
request.expects(:set_form_data).with({}).once
|
144
|
+
|
145
|
+
client.post(path)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "put" do
|
150
|
+
it 'puts' do
|
151
|
+
path = '/put'
|
152
|
+
uri = URI.parse('http://localhost/put')
|
153
|
+
|
154
|
+
client.expects(:make_uri).with(path).returns(uri).once
|
155
|
+
Net::HTTP::Put.expects(:new).with(uri).returns(request)
|
156
|
+
|
157
|
+
client.expects(:make_request).with(request, uri).returns(response)
|
158
|
+
request.expects(:set_form_data).with({}).once
|
159
|
+
|
160
|
+
client.put(path)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "patch" do
|
165
|
+
it 'patch' do
|
166
|
+
path = '/patch'
|
167
|
+
uri = URI.parse('http://localhost/patch')
|
168
|
+
|
169
|
+
client.expects(:make_uri).with(path).returns(uri).once
|
170
|
+
Net::HTTP::Patch.expects(:new).with(uri).returns(request)
|
171
|
+
|
172
|
+
client.expects(:make_request).with(request, uri).returns(response)
|
173
|
+
request.expects(:set_form_data).with({}).once
|
174
|
+
|
175
|
+
client.patch(path)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "delete" do
|
180
|
+
it 'delete' do
|
181
|
+
path = '/delete'
|
182
|
+
uri = URI.parse('http://localhost/delete')
|
183
|
+
|
184
|
+
client.expects(:make_uri).with(path).returns(uri).once
|
185
|
+
Net::HTTP::Delete.expects(:new).with(uri).returns(request)
|
186
|
+
|
187
|
+
client.expects(:make_request).with(request, uri).returns(response)
|
188
|
+
request.expects(:set_form_data).with({}).once
|
189
|
+
|
190
|
+
client.delete(path)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "parse_response" do
|
195
|
+
let(:response) { mock }
|
196
|
+
let(:valid_json) { '{"a": 1}' }
|
197
|
+
let(:invalid_json) { '{"a": 1, "b" => 2}' }
|
198
|
+
|
199
|
+
before do
|
200
|
+
client.expects(:raise_errors).with(response).once
|
201
|
+
end
|
202
|
+
|
203
|
+
it "204 no content" do
|
204
|
+
response.expects(:code).returns(204)
|
205
|
+
response.expects(:body).never
|
206
|
+
::JSON.expects(:parse).never
|
207
|
+
|
208
|
+
client.parse_response(response)
|
209
|
+
end
|
210
|
+
|
211
|
+
it "valid json" do
|
212
|
+
response.expects(:code).returns(200)
|
213
|
+
response.expects(:body).returns(valid_json).once
|
214
|
+
::JSON.expects(:parse).with(valid_json)
|
215
|
+
|
216
|
+
client.parse_response(response)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "invalid json" do
|
220
|
+
response.expects(:code).returns(200)
|
221
|
+
response.expects(:body).returns(invalid_json).once
|
222
|
+
::JSON.expects(:parse).with(invalid_json)
|
223
|
+
|
224
|
+
client.parse_response(response)
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
describe "raise_errors_for_cloudfront_response" do
|
230
|
+
let(:header) { mock }
|
231
|
+
let(:cloudfront_server) { 'Cloudfront' }
|
232
|
+
let(:nginx_server) { 'nginx/1.2.9' }
|
233
|
+
|
234
|
+
before do
|
235
|
+
response.expects(:header).returns(header)
|
236
|
+
end
|
237
|
+
|
238
|
+
it "cloudfront" do
|
239
|
+
header.expects(:[]).with('Server').returns(cloudfront_server)
|
240
|
+
|
241
|
+
->{ client.raise_errors_for_cloudfront_response(response) }.must_raise(Hover::Client::Unavailable)
|
242
|
+
end
|
243
|
+
|
244
|
+
it "nginx" do
|
245
|
+
header.expects(:[]).with('Server').returns(nginx_server)
|
246
|
+
|
247
|
+
client.raise_errors_for_cloudfront_response(response)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
describe "raise_errors" do
|
252
|
+
before do
|
253
|
+
response.expects(:body).once
|
254
|
+
end
|
255
|
+
|
256
|
+
{
|
257
|
+
400 => Hover::Client::BadRequest,
|
258
|
+
401 => Hover::Client::Unauthorized,
|
259
|
+
403 => Hover::Client::General,
|
260
|
+
404 => Hover::Client::NotFound,
|
261
|
+
500 => Hover::Client::InternalError,
|
262
|
+
502 => Hover::Client::Unavailable,
|
263
|
+
503 => Hover::Client::Unavailable
|
264
|
+
}.each do |code, exception_class|
|
265
|
+
it code.to_s do
|
266
|
+
response.expects(:code).returns(code.to_s).twice
|
267
|
+
|
268
|
+
-> { client.raise_errors(response) }.must_raise(exception_class)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
it "200" do
|
273
|
+
response.expects(:code).returns('200').twice
|
274
|
+
client.raise_errors(response)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|