harpy 1.0.0 → 2.0.0.preview1
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 +5 -5
- data/.forgejo/workflows/test.yml +33 -0
- data/.github/workflows/test.yml +20 -0
- data/.gitignore +2 -1
- data/README.md +8 -9
- data/harpy.gemspec +8 -5
- data/lib/harpy/client.rb +51 -13
- data/lib/harpy/entry_point.rb +3 -3
- data/lib/harpy/gem_version.rb +14 -0
- data/lib/harpy/resource.rb +113 -96
- data/lib/harpy/version.rb +9 -0
- data/lib/harpy.rb +3 -2
- data/spec/harpy/client_spec.rb +85 -36
- data/spec/harpy/entry_point_spec.rb +19 -19
- data/spec/harpy/resource_spec.rb +254 -255
- data/spec/harpy_spec.rb +20 -20
- data/spec/spec_helper.rb +31 -2
- metadata +63 -51
- data/.travis.yml +0 -9
- data/Gemfile.lock +0 -56
data/spec/harpy/client_spec.rb
CHANGED
|
@@ -5,92 +5,141 @@ describe Harpy::Client do
|
|
|
5
5
|
let(:users_url) { "http://localhost/users" }
|
|
6
6
|
|
|
7
7
|
context "by default" do
|
|
8
|
-
|
|
8
|
+
describe '#options' do
|
|
9
|
+
subject { super().options }
|
|
10
|
+
it { is_expected.to be_empty }
|
|
11
|
+
end
|
|
9
12
|
end
|
|
10
13
|
|
|
11
14
|
context "initialized with options" do
|
|
12
15
|
let(:options) { {:username => "harpy", :password => "spec"} }
|
|
13
16
|
subject { Harpy::Client.new(options) }
|
|
14
|
-
|
|
17
|
+
|
|
18
|
+
describe '#options' do
|
|
19
|
+
subject { super().options }
|
|
20
|
+
it { is_expected.to eq(options) }
|
|
21
|
+
end
|
|
15
22
|
end
|
|
16
23
|
|
|
17
24
|
[:get, :head, :post, :put, :patch, :delete].each do |method|
|
|
18
25
|
describe "##{method}(url, opts={})" do
|
|
19
26
|
context "with one url" do
|
|
20
27
|
before do
|
|
21
|
-
|
|
22
|
-
Typhoeus.stub(entry_url, method: method){@expected}
|
|
28
|
+
stub_request(method, entry_url).to_return(status: 200)
|
|
23
29
|
end
|
|
30
|
+
|
|
24
31
|
it "sends a #{method.to_s.upcase} to the url" do
|
|
25
|
-
subject.send(method, entry_url)
|
|
32
|
+
response = subject.send(method, entry_url)
|
|
33
|
+
expect(response.status).to eq(200)
|
|
34
|
+
expect(WebMock).to have_requested(method, entry_url)
|
|
26
35
|
end
|
|
36
|
+
|
|
27
37
|
it "merges options" do
|
|
28
38
|
client = Harpy::Client.new :headers => {"Authorization" => "spec"}
|
|
29
|
-
|
|
39
|
+
stub_request(method, entry_url).to_return(status: 200)
|
|
30
40
|
response = client.send method, entry_url, :headers => {"X-Files" => "Harpy"}
|
|
31
|
-
|
|
41
|
+
expect(WebMock).to have_requested(method, entry_url).with(headers: {
|
|
42
|
+
"X-Files" => "Harpy",
|
|
43
|
+
"Authorization" => "spec"
|
|
44
|
+
})
|
|
32
45
|
end
|
|
33
46
|
end
|
|
47
|
+
|
|
34
48
|
context "with multiple urls" do
|
|
35
49
|
it "does not execute requests" do
|
|
36
|
-
|
|
50
|
+
expect {
|
|
37
51
|
subject.send method, [entry_url, users_url]
|
|
38
|
-
}.
|
|
52
|
+
}.not_to raise_error
|
|
39
53
|
end
|
|
40
|
-
|
|
54
|
+
|
|
55
|
+
it "returns one request per url" do
|
|
41
56
|
requests = subject.send method, [entry_url, users_url]
|
|
42
|
-
requests.size.
|
|
43
|
-
requests.collect{|
|
|
44
|
-
requests.collect
|
|
57
|
+
expect(requests.size).to eq(2)
|
|
58
|
+
expect(requests.collect{|request| request.verb.downcase.to_sym}).to match_array([method, method])
|
|
59
|
+
expect(requests.collect{|request| request.uri.to_s}).to match_array([entry_url, users_url])
|
|
45
60
|
end
|
|
61
|
+
|
|
46
62
|
it "merges options" do
|
|
47
63
|
client = Harpy::Client.new :headers => {"Authorization" => "spec"}
|
|
48
64
|
requests = client.send method, [entry_url, users_url], :headers => {"X-Files" => "Harpy"}
|
|
49
65
|
requests.each do |request|
|
|
50
|
-
request.
|
|
66
|
+
expect(request.headers["x-files"]).to eq("Harpy")
|
|
67
|
+
expect(request.headers["authorization"]).to eq("spec")
|
|
51
68
|
end
|
|
52
69
|
end
|
|
53
70
|
end
|
|
54
71
|
end
|
|
55
72
|
end
|
|
73
|
+
|
|
74
|
+
describe "HTTPX request options" do
|
|
75
|
+
it "encodes query parameters" do
|
|
76
|
+
stub_request(:get, "#{users_url}?active=true").to_return(status: 200)
|
|
77
|
+
|
|
78
|
+
response = subject.get(users_url, params: {active: true})
|
|
79
|
+
|
|
80
|
+
expect(response.status).to eq(200)
|
|
81
|
+
expect(WebMock).to have_requested(:get, "#{users_url}?active=true")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "maps username and password to basic authentication" do
|
|
85
|
+
stub_request(:get, entry_url).with(headers: {"Authorization" => "Basic aGFycHk6c3BlYw=="}).to_return(status: 200)
|
|
86
|
+
|
|
87
|
+
response = Harpy::Client.new(username: "harpy", password: "spec").get(entry_url)
|
|
88
|
+
|
|
89
|
+
expect(response.status).to eq(200)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "maps legacy timeout and SSL options" do
|
|
93
|
+
request = Harpy::Client.new(timeout: 5000, ssl_verifypeer: false, ssl_verifyhost: 0).get([entry_url]).first
|
|
94
|
+
|
|
95
|
+
expect(request.options.timeout.total_request_timeout).to eq(5)
|
|
96
|
+
expect(request.options.ssl).to include(verify_mode: OpenSSL::SSL::VERIFY_NONE, verify_hostname: false)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
56
100
|
describe "#run(requests)" do
|
|
57
101
|
before do
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
Typhoeus.stub(entry_url, method: :get){ @entry_response }
|
|
62
|
-
Typhoeus.stub(users_url, method: :get){ @users_response }
|
|
102
|
+
stub_request(:get, entry_url).to_return(status: 200, body: "entry")
|
|
103
|
+
stub_request(:get, users_url).to_return(status: 200, body: "users")
|
|
63
104
|
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
105
|
+
|
|
106
|
+
it "submits the requests together to HTTPX" do
|
|
107
|
+
requests = subject.get([entry_url, users_url])
|
|
108
|
+
expect(subject.instance_variable_get(:@session)).to receive(:request).with(*requests).and_call_original
|
|
109
|
+
subject.run requests
|
|
67
110
|
end
|
|
111
|
+
|
|
68
112
|
it "returns responses" do
|
|
69
113
|
responses = subject.run subject.get([entry_url, users_url])
|
|
70
|
-
responses.
|
|
114
|
+
expect(responses.map(&:body)).to match_array(["entry", "users"])
|
|
71
115
|
end
|
|
72
|
-
|
|
116
|
+
|
|
117
|
+
it "fills in each request response" do
|
|
73
118
|
requests = subject.get([entry_url, users_url])
|
|
74
119
|
subject.run requests
|
|
75
|
-
requests
|
|
76
|
-
requests[1].response.should == @users_response
|
|
120
|
+
expect(requests.map{|request| request.response.body}).to eq(["entry", "users"])
|
|
77
121
|
end
|
|
78
122
|
end
|
|
123
|
+
|
|
79
124
|
describe "#invalid_code(response)" do
|
|
80
125
|
it "raises Harpy::ClientTimeout on request timeout" do
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
126
|
+
error = HTTPX::RequestTimeoutError.new(nil, nil, 1)
|
|
127
|
+
expect {
|
|
128
|
+
subject.invalid_code httpx_error_response(error)
|
|
129
|
+
}.to raise_error Harpy::ClientTimeout
|
|
84
130
|
end
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
131
|
+
|
|
132
|
+
it "raises Harpy::ClientError on transport error" do
|
|
133
|
+
error = HTTPX::ConnectionError.new("Could not connect to server")
|
|
134
|
+
expect {
|
|
135
|
+
subject.invalid_code httpx_error_response(error)
|
|
136
|
+
}.to raise_error Harpy::ClientError, "Could not connect to server"
|
|
89
137
|
end
|
|
138
|
+
|
|
90
139
|
it "raises Harpy::InvalidResponseCode with code otherwise" do
|
|
91
|
-
|
|
92
|
-
subject.invalid_code
|
|
93
|
-
}.
|
|
140
|
+
expect {
|
|
141
|
+
subject.invalid_code httpx_response(:code => 404)
|
|
142
|
+
}.to raise_error Harpy::InvalidResponseCode, "404"
|
|
94
143
|
end
|
|
95
144
|
end
|
|
96
145
|
end
|
|
@@ -5,29 +5,29 @@ describe Harpy::EntryPoint do
|
|
|
5
5
|
subject { Harpy::EntryPoint.new url}
|
|
6
6
|
|
|
7
7
|
it "should store url" do
|
|
8
|
-
subject.url.
|
|
8
|
+
expect(subject.url).to eq(url)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
describe "#resource_url(resource_type)" do
|
|
12
12
|
let(:company_url) { "#{url}/company"}
|
|
13
13
|
let(:json_response) { %Q|{"link": [{"rel": "company", "href": "#{company_url}"}]}| }
|
|
14
|
-
let(:success_response) {
|
|
15
|
-
let(:error_response) {
|
|
14
|
+
let(:success_response) { httpx_response :code => 200, :body => json_response }
|
|
15
|
+
let(:error_response) { httpx_response :code => 500 }
|
|
16
16
|
it "gets entry point from url using client" do
|
|
17
|
-
Harpy.client.
|
|
17
|
+
expect(Harpy.client).to receive(:get).with(url).and_return success_response
|
|
18
18
|
subject.resource_url "user"
|
|
19
19
|
end
|
|
20
20
|
it "return nil if no link for resource_type" do
|
|
21
|
-
Harpy.client.
|
|
22
|
-
subject.resource_url("user").
|
|
21
|
+
expect(Harpy.client).to receive(:get).with(url).and_return success_response
|
|
22
|
+
expect(subject.resource_url("user")).to be_nil
|
|
23
23
|
end
|
|
24
24
|
it "return url for existing resource_type" do
|
|
25
|
-
Harpy.client.
|
|
26
|
-
subject.resource_url("company_url").
|
|
25
|
+
expect(Harpy.client).to receive(:get).with(url).and_return success_response
|
|
26
|
+
expect(subject.resource_url("company_url")).to be_nil
|
|
27
27
|
end
|
|
28
28
|
it "delegates response code != 200 to client" do
|
|
29
|
-
Harpy.client.
|
|
30
|
-
Harpy.client.
|
|
29
|
+
expect(Harpy.client).to receive(:get).with(url).and_return error_response
|
|
30
|
+
expect(Harpy.client).to receive(:invalid_code).with error_response
|
|
31
31
|
subject.resource_url("company_url")
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -35,20 +35,20 @@ describe Harpy::EntryPoint do
|
|
|
35
35
|
describe "#urn(urn)" do
|
|
36
36
|
let(:urn) { "urn:harpy:company:1" }
|
|
37
37
|
let(:company_url) { "#{url}/company/1"}
|
|
38
|
-
let(:success_response) {
|
|
39
|
-
let(:error_response) {
|
|
40
|
-
let(:not_found_response) {
|
|
38
|
+
let(:success_response) { httpx_response :code => 301, :headers => "Location: #{company_url}" }
|
|
39
|
+
let(:error_response) { httpx_response :code => 500 }
|
|
40
|
+
let(:not_found_response) { httpx_response :code => 404 }
|
|
41
41
|
it "query remote for this urn using client" do
|
|
42
|
-
Harpy.client.
|
|
43
|
-
subject.urn(urn).
|
|
42
|
+
expect(Harpy.client).to receive(:get).with("#{url}/#{urn}").and_return success_response
|
|
43
|
+
expect(subject.urn(urn)).to eq(company_url)
|
|
44
44
|
end
|
|
45
45
|
it "return nil if not found" do
|
|
46
|
-
Harpy.client.
|
|
47
|
-
subject.urn(urn).
|
|
46
|
+
expect(Harpy.client).to receive(:get).with("#{url}/#{urn}").and_return not_found_response
|
|
47
|
+
expect(subject.urn(urn)).to be_nil
|
|
48
48
|
end
|
|
49
49
|
it "delegates response code != 301 or 404 to client" do
|
|
50
|
-
Harpy.client.
|
|
51
|
-
Harpy.client.
|
|
50
|
+
expect(Harpy.client).to receive(:get).with("#{url}/#{urn}").and_return error_response
|
|
51
|
+
expect(Harpy.client).to receive(:invalid_code).with error_response
|
|
52
52
|
subject.urn(urn)
|
|
53
53
|
end
|
|
54
54
|
end
|