web_fetch 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Makefile +6 -0
- data/README.md +19 -19
- data/Rakefile +6 -0
- data/doc/examples/blocking_requests.rb +3 -3
- data/doc/examples/non_blocking_requests.rb +2 -2
- data/doc/examples/use_uid_for_request.rb +3 -3
- data/docker/Dockerfile +3 -1
- data/lib/web_fetch.rb +1 -1
- data/lib/web_fetch/client.rb +8 -8
- data/lib/web_fetch/concerns/http_helpers.rb +2 -0
- data/lib/web_fetch/promise.rb +10 -42
- data/lib/web_fetch/{result.rb → response.rb} +5 -2
- data/lib/web_fetch/server.rb +1 -0
- data/lib/web_fetch/version.rb +1 -1
- data/spec/client_spec.rb +10 -9
- data/spec/gatherer_spec.rb +12 -12
- data/spec/promise_spec.rb +27 -20
- data/spec/resources_spec.rb +15 -15
- data/spec/{result_spec.rb → response_spec.rb} +10 -3
- data/spec/router_spec.rb +2 -2
- data/web_fetch.gemspec +1 -0
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19518942fe1e37355b4cf571590fb7d844c0eded61b035c036bb923a114e0aa4
|
4
|
+
data.tar.gz: ba143ee2c1244b5c37459f1057beaba210945f310c4d8174b0253d9cec90d0f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f37dcd9cca372a63f47737ff619a996cfa68494038d1746d3f28445f7ad7fd8c9651e43f284e2ece92696b9883a28295bedc9e8d55789fe91aeb4d60032a342e
|
7
|
+
data.tar.gz: 0542a7735cda7d6eddaee2a94df7b5143934184a4902d3c21c2546dd2361d74226916efd783f635828db73d0eec49e10400d50594cab82aa094faf83a63a6231
|
data/.gitignore
CHANGED
data/Makefile
ADDED
data/README.md
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# WebFetch
|
2
2
|
|
3
3
|
```
|
4
|
-
|
5
|
-
|
6
|
-
--Nickelback
|
4
|
+
Better all together than just one at a time
|
5
|
+
--Nickelback
|
7
6
|
```
|
8
7
|
|
9
8
|
## Overview
|
@@ -66,7 +65,7 @@ end
|
|
66
65
|
|
67
66
|
Only `url` is required. The default HTTP method is `GET`.
|
68
67
|
|
69
|
-
Anything assigned to `custom` will be returned with the final
|
68
|
+
Anything assigned to `custom` will be returned with the final response (available by calling `#custom` on the response). This may be useful if you need to tag each request with your own custom identifier, for example. Anything you assign here will have no bearing whatsoever on the HTTP request.
|
70
69
|
|
71
70
|
If you prefer to build a request from a hash, you can call `WebFetch::Request.from_hash`
|
72
71
|
|
@@ -91,37 +90,38 @@ promises = client.gather([request])
|
|
91
90
|
|
92
91
|
`WebFetch::Client#gather` accepts an array of `WebFetch::Request` objects and immediately returns an array of `WebFetch::Promise` objects. WebFetch will process all requests in the background concurrently.
|
93
92
|
|
94
|
-
To retrieve the
|
93
|
+
To retrieve the response of a request, call `WebFetch::Promise#fetch`
|
95
94
|
|
96
95
|
``` ruby
|
97
|
-
|
96
|
+
response = promises.first.fetch
|
98
97
|
|
99
98
|
# Available methods:
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
99
|
+
response.body
|
100
|
+
response.headers
|
101
|
+
response.status # HTTP status code
|
102
|
+
response.success? # False if a network error (not HTTP error) occurred
|
103
|
+
response.error # Underlying network error if applicable
|
104
|
+
response.response_time
|
105
|
+
response.request # The original request, provided as a `WebFetch::Request` object
|
106
106
|
```
|
107
107
|
|
108
|
-
Note that `WebFech::Promise#fetch` will block until the
|
108
|
+
Note that `WebFech::Promise#fetch` will block until the response is complete by default. If you want to continue executing other code if the response is not ready (e.g. to see if any other responses are ready), you can pass `wait: false`
|
109
109
|
|
110
110
|
``` ruby
|
111
|
-
|
111
|
+
response = promises.first.fetch(wait: false)
|
112
112
|
```
|
113
113
|
|
114
|
-
|
114
|
+
If the response has not yet returned, `response.pending?` will be `true`.
|
115
115
|
|
116
116
|
Alternatively, you can call `WebFetch::Promise#complete?` to check if a request has finished before waiting for the response:
|
117
117
|
|
118
118
|
``` ruby
|
119
|
-
|
119
|
+
response = promises.first.fetch if promises.first.complete?
|
120
120
|
```
|
121
121
|
|
122
|
-
### Fetching
|
122
|
+
### Fetching responses later
|
123
123
|
|
124
|
-
In some cases you may need to fetch the
|
124
|
+
In some cases you may need to fetch the response of a request in a different context to which you initiated it. A unique ID is available for each *Promise* which can be used to fetch the response from a separate *Client* instance:
|
125
125
|
|
126
126
|
``` ruby
|
127
127
|
client = WebFetch::Client.new('localhost', 8077)
|
@@ -132,7 +132,7 @@ uid = promises.first.uid
|
|
132
132
|
|
133
133
|
# Later ...
|
134
134
|
client = WebFetch::Client.new('localhost', 8077)
|
135
|
-
|
135
|
+
response = client.fetch(uid)
|
136
136
|
```
|
137
137
|
|
138
138
|
This can be useful if your web application initiates requests in one controller action and fetches them in another; the `uid` can be stored in a database and used to fetch the request later on.
|
data/Rakefile
ADDED
@@ -21,9 +21,9 @@ def blocking_requests
|
|
21
21
|
promises = client.gather(requests)
|
22
22
|
|
23
23
|
promises.each do |promise|
|
24
|
-
|
25
|
-
puts
|
26
|
-
puts "Success: #{
|
24
|
+
response = promise.fetch(wait: true) # Will block (default behaviour)
|
25
|
+
puts response.body[0..100]
|
26
|
+
puts "Success: #{response.success?}"
|
27
27
|
end
|
28
28
|
|
29
29
|
client.stop
|
@@ -22,8 +22,8 @@ def non_blocking_requests
|
|
22
22
|
|
23
23
|
while promises.any? { |promise| !promise.complete? }
|
24
24
|
promises.each do |promise|
|
25
|
-
|
26
|
-
puts
|
25
|
+
response = promise.fetch(wait: false) # Will not block
|
26
|
+
puts response.body[0..100] unless response == :pending
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -15,11 +15,11 @@ def use_uid_for_request
|
|
15
15
|
promises = client.gather([request])
|
16
16
|
uid = promises.first.uid
|
17
17
|
while true
|
18
|
-
|
19
|
-
break unless
|
18
|
+
response = client.fetch(uid, wait: false)
|
19
|
+
break unless response == :pending
|
20
20
|
end
|
21
21
|
|
22
|
-
puts
|
22
|
+
puts response.body[0..100]
|
23
23
|
|
24
24
|
client.stop
|
25
25
|
end
|
data/docker/Dockerfile
CHANGED
data/lib/web_fetch.rb
CHANGED
data/lib/web_fetch/client.rb
CHANGED
@@ -57,9 +57,7 @@ module WebFetch
|
|
57
57
|
outcome = block ? retrieve_by_uid(uid) : find_by_uid(uid)
|
58
58
|
no_request_error(uid) if outcome.nil?
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
new_result(outcome)
|
60
|
+
new_response(outcome)
|
63
61
|
end
|
64
62
|
|
65
63
|
def retrieve_by_uid(uid)
|
@@ -104,20 +102,22 @@ module WebFetch
|
|
104
102
|
raise RequestNotFoundError, [I18n.t('no_request', uid: uid)]
|
105
103
|
end
|
106
104
|
|
107
|
-
def
|
108
|
-
response = outcome[:response]
|
109
|
-
# FIXME: This is sort-of duplicated from `Promise#
|
105
|
+
def new_response(outcome)
|
106
|
+
response = outcome[:response] || {}
|
107
|
+
# FIXME: This is sort-of duplicated from `Promise#new_response` but we
|
110
108
|
# build it very slightly differently. This means we have to update in
|
111
109
|
# both places if we change the structure. Not quite sure how to unify
|
112
110
|
# this and ensure the same structure in both places.
|
113
|
-
|
111
|
+
Response.new(
|
112
|
+
pending: outcome[:pending],
|
114
113
|
body: response[:body],
|
115
114
|
headers: response[:headers],
|
116
115
|
status: response[:status],
|
117
116
|
success: response[:success],
|
118
117
|
error: response[:error],
|
119
118
|
uid: outcome[:uid],
|
120
|
-
response_time: response[:response_time]
|
119
|
+
response_time: response[:response_time],
|
120
|
+
request: outcome[:request]
|
121
121
|
)
|
122
122
|
end
|
123
123
|
|
@@ -61,6 +61,7 @@ module WebFetch
|
|
61
61
|
status: result.response_header.status,
|
62
62
|
response_time: request[:response_time]
|
63
63
|
},
|
64
|
+
request: request[:request],
|
64
65
|
uid: request[:uid] }
|
65
66
|
end
|
66
67
|
|
@@ -81,6 +82,7 @@ module WebFetch
|
|
81
82
|
response_time: request[:response_time],
|
82
83
|
error: (result.error&.inspect)
|
83
84
|
},
|
85
|
+
request: request[:request],
|
84
86
|
uid: request[:uid] }
|
85
87
|
end
|
86
88
|
|
data/lib/web_fetch/promise.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module WebFetch
|
4
4
|
class Promise
|
5
|
-
attr_reader :uid, :request, :
|
5
|
+
attr_reader :uid, :request, :response
|
6
6
|
|
7
7
|
def initialize(client, options = {})
|
8
8
|
@client = client
|
@@ -11,11 +11,10 @@ module WebFetch
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def fetch(options = {})
|
14
|
-
return @
|
14
|
+
return @response if complete?
|
15
15
|
|
16
|
-
|
17
|
-
@
|
18
|
-
(@result = build_result)
|
16
|
+
wait = options.fetch(:wait, true)
|
17
|
+
(@response = @client.fetch(@uid, wait: wait))
|
19
18
|
end
|
20
19
|
|
21
20
|
def custom
|
@@ -23,56 +22,25 @@ module WebFetch
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def complete?
|
26
|
-
return false if @
|
27
|
-
return false if pending?
|
28
|
-
return true if @result
|
25
|
+
return false if @response.nil?
|
29
26
|
|
30
|
-
|
27
|
+
@response.complete?
|
31
28
|
end
|
32
29
|
|
33
30
|
def pending?
|
34
|
-
return false if @
|
31
|
+
return false if @response.nil?
|
35
32
|
|
36
|
-
@
|
33
|
+
@response.pending?
|
37
34
|
end
|
38
35
|
|
39
36
|
def success?
|
40
|
-
complete? && @
|
37
|
+
complete? && @response.success?
|
41
38
|
end
|
42
39
|
|
43
40
|
def error
|
44
41
|
return nil unless complete?
|
45
42
|
|
46
|
-
@
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def find_or_retrieve(block)
|
52
|
-
block ? @client.retrieve_by_uid(@uid) : @client.find_by_uid(@uid)
|
53
|
-
end
|
54
|
-
|
55
|
-
def build_result
|
56
|
-
return nil if @raw_result.nil?
|
57
|
-
return :pending if @raw_result[:pending]
|
58
|
-
return nil unless @raw_result[:response]
|
59
|
-
|
60
|
-
response = @raw_result[:response]
|
61
|
-
new_result(response)
|
62
|
-
end
|
63
|
-
|
64
|
-
def new_result(response)
|
65
|
-
# XXX: Any changes to this structure need to be reflected by
|
66
|
-
# `Client#new_result`
|
67
|
-
Result.new(
|
68
|
-
body: response[:body],
|
69
|
-
headers: response[:headers],
|
70
|
-
status: response[:status],
|
71
|
-
success: @raw_result[:response][:success],
|
72
|
-
error: @raw_result[:response][:error],
|
73
|
-
uid: @uid,
|
74
|
-
response_time: @raw_result[:response_time]
|
75
|
-
)
|
43
|
+
@response.error
|
76
44
|
end
|
77
45
|
end
|
78
46
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module WebFetch
|
4
|
-
class
|
5
|
-
attr_reader :body, :headers, :status, :error, :uid, :response_time
|
4
|
+
class Response
|
5
|
+
attr_reader :request, :body, :headers, :status, :error, :uid, :response_time
|
6
6
|
|
7
7
|
def initialize(options = {})
|
8
8
|
@pending = options.fetch(:pending, false)
|
@@ -11,6 +11,7 @@ module WebFetch
|
|
11
11
|
@body = options.fetch(:body)
|
12
12
|
@headers = options.fetch(:headers)
|
13
13
|
@status = options.fetch(:status)
|
14
|
+
@request = Request.from_hash(options.fetch(:request))
|
14
15
|
@success = options.fetch(:success)
|
15
16
|
@error = options.fetch(:error)
|
16
17
|
@uid = options.fetch(:uid)
|
@@ -18,6 +19,8 @@ module WebFetch
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def pending?
|
22
|
+
return false if @pending.nil?
|
23
|
+
|
21
24
|
@pending
|
22
25
|
end
|
23
26
|
|
data/lib/web_fetch/server.rb
CHANGED
data/lib/web_fetch/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -33,10 +33,11 @@ describe WebFetch::Client do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'makes `gather` requests to a running server' do
|
36
|
-
|
37
|
-
expect(
|
38
|
-
expect(
|
39
|
-
expect(
|
36
|
+
response = client.gather([web_request])
|
37
|
+
expect(response.first).to be_a WebFetch::Promise
|
38
|
+
expect(response.first.uid).to_not be_nil
|
39
|
+
expect(response.first.custom).to eql(my_key: 'my_value')
|
40
|
+
expect(response.first.request).to be_a WebFetch::Request
|
40
41
|
end
|
41
42
|
|
42
43
|
it 'passes any WebFetch server errors back to the user' do
|
@@ -62,7 +63,7 @@ describe WebFetch::Client do
|
|
62
63
|
|
63
64
|
subject { client.fetch(responses.first.uid) }
|
64
65
|
|
65
|
-
it { is_expected.to be_a WebFetch::
|
66
|
+
it { is_expected.to be_a WebFetch::Response }
|
66
67
|
|
67
68
|
context 'no matching request found' do
|
68
69
|
subject { proc { client.fetch('not-found') } }
|
@@ -75,8 +76,8 @@ describe WebFetch::Client do
|
|
75
76
|
|
76
77
|
describe '#retrieve_by_uid' do
|
77
78
|
it 'retrieves a gathered item' do
|
78
|
-
|
79
|
-
uid =
|
79
|
+
response = client.gather([{ url: 'http://blah.blah/success' }])
|
80
|
+
uid = response.first.uid
|
80
81
|
|
81
82
|
retrieved = client.retrieve_by_uid(uid)
|
82
83
|
expect(retrieved[:response][:status]).to eql 200
|
@@ -96,8 +97,8 @@ describe WebFetch::Client do
|
|
96
97
|
describe '#find_by_uid' do
|
97
98
|
it 'returns a ready status when has been fetched' do
|
98
99
|
pending 'Find a good way to create a slow response without locking EM'
|
99
|
-
|
100
|
-
uid =
|
100
|
+
response = client.gather([{ url: 'http://blah.blah/slow_success' }])
|
101
|
+
uid = response.first[:uid]
|
101
102
|
|
102
103
|
found = client.find_by_uid(uid)
|
103
104
|
expect(found[:pending]).to be true
|
data/spec/gatherer_spec.rb
CHANGED
@@ -50,9 +50,9 @@ describe WebFetch::Gatherer do
|
|
50
50
|
|
51
51
|
describe '#start' do
|
52
52
|
it 'returns a hash containing sha1 hashes of requests' do
|
53
|
-
|
53
|
+
response = described_class.new(server, valid_params).start
|
54
54
|
hash = Digest::SHA1.new.digest(JSON.dump(valid_params[:requests].first))
|
55
|
-
expect(
|
55
|
+
expect(response[:requests].first[:hash]).to eql Digest.hexencode(hash)
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'respects url, headers, http method and query when calculating sha1' do
|
@@ -67,17 +67,17 @@ describe WebFetch::Gatherer do
|
|
67
67
|
req5 = { url: 'http://blah', query_string: 'a=1',
|
68
68
|
headers: { 'Content-Type' => 'hello' },
|
69
69
|
method: 'PUT' }
|
70
|
-
|
70
|
+
responses = [req1, req2, req3, req4, req5].map do |req|
|
71
71
|
described_class.new(server, requests: [req], _server: server).start
|
72
72
|
end
|
73
|
-
hashes =
|
73
|
+
hashes = responses.map { |res| res[:requests].first[:hash] }
|
74
74
|
expect(hashes.uniq.length).to eql 5
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'returns a hash containing unique IDs for requests' do
|
78
|
-
|
79
|
-
uid1 =
|
80
|
-
uid2 =
|
78
|
+
response = described_class.new(server, valid_params).start
|
79
|
+
uid1 = response[:requests][0][:uid]
|
80
|
+
uid2 = response[:requests][1][:uid]
|
81
81
|
expect(uid1).to_not eql uid2
|
82
82
|
end
|
83
83
|
|
@@ -87,8 +87,8 @@ describe WebFetch::Gatherer do
|
|
87
87
|
# the uid of the delegated request
|
88
88
|
params = { requests: [url: '-', bob: 'hello'],
|
89
89
|
_server: server }
|
90
|
-
|
91
|
-
expect(
|
90
|
+
response = described_class.new(server, params).start
|
91
|
+
expect(response[:requests].first[:request][:bob]).to eql 'hello'
|
92
92
|
end
|
93
93
|
|
94
94
|
it 'does not affect request hash' do
|
@@ -97,12 +97,12 @@ describe WebFetch::Gatherer do
|
|
97
97
|
# otherwise duplicate requests
|
98
98
|
params1 = { requests: [url: 'http://blah', bob: 'hello'],
|
99
99
|
_server: server }
|
100
|
-
|
100
|
+
response1 = described_class.new(server, params1).start
|
101
101
|
|
102
102
|
params2 = { requests: [url: 'http://blah', not_bob: 'good bye'],
|
103
103
|
_server: server }
|
104
|
-
|
105
|
-
expect(
|
104
|
+
response2 = described_class.new(server, params2).start
|
105
|
+
expect(response1[:requests][0][:hash]).to eql response2[:requests][0][:hash]
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
data/spec/promise_spec.rb
CHANGED
@@ -5,37 +5,42 @@ RSpec.describe WebFetch::Promise do
|
|
5
5
|
let(:request) { { url: 'http://blah', custom: { my_key: 'my_value' } } }
|
6
6
|
let(:options) { { uid: uid, request: request } }
|
7
7
|
let(:client) { WebFetch::Client.new('test-host', 8080) }
|
8
|
-
let(:response) { described_class.new(client, options) }
|
9
8
|
let(:retrieve_url) { "http://#{client.host}:#{client.port}/retrieve/#{uid}" }
|
10
9
|
let(:find_url) { "http://#{client.host}:#{client.port}/find/#{uid}" }
|
11
10
|
|
12
11
|
let(:client_success) do
|
13
|
-
double(
|
12
|
+
double(fetch: double('success',
|
13
|
+
complete?: true, pending?: false, success?: true, error: nil
|
14
|
+
))
|
14
15
|
end
|
15
16
|
|
16
17
|
let(:client_failure) do
|
17
|
-
double(
|
18
|
+
double(fetch: double('failure',
|
19
|
+
complete?: true, pending?: false, success?: false, error: 'foo'
|
20
|
+
))
|
18
21
|
end
|
19
22
|
|
20
23
|
let(:client_pending) do
|
21
|
-
double(
|
24
|
+
double(fetch: double('pending',
|
25
|
+
complete?: false, pending?: true, error: nil
|
26
|
+
))
|
22
27
|
end
|
23
28
|
|
24
29
|
let(:client_not_started) do
|
25
|
-
double(
|
30
|
+
double('not started', fetch: nil)
|
26
31
|
end
|
27
32
|
|
28
|
-
subject {
|
33
|
+
subject(:promise) { described_class.new(client, options) }
|
29
34
|
|
30
35
|
it { is_expected.to be_a described_class }
|
31
36
|
|
32
37
|
describe '#fetch' do
|
33
38
|
before do
|
34
|
-
stub_request(:get, retrieve_url).to_return(body: {}.to_json)
|
35
|
-
stub_request(:get, find_url).to_return(body: {}.to_json)
|
39
|
+
stub_request(:get, retrieve_url).to_return(body: { request: {} }.to_json)
|
40
|
+
stub_request(:get, find_url).to_return(body: { request: {} }.to_json)
|
36
41
|
end
|
37
42
|
|
38
|
-
subject {
|
43
|
+
subject { promise.fetch(fetch_options) }
|
39
44
|
|
40
45
|
context 'blocking call' do
|
41
46
|
let(:fetch_options) { { wait: true } }
|
@@ -48,29 +53,31 @@ RSpec.describe WebFetch::Promise do
|
|
48
53
|
end
|
49
54
|
|
50
55
|
context 'default (blocking)' do
|
51
|
-
subject {
|
56
|
+
subject { promise.fetch }
|
52
57
|
it { is_expected.to have_requested(:get, retrieve_url) }
|
53
58
|
end
|
54
59
|
end
|
55
60
|
|
56
|
-
describe '#
|
61
|
+
describe '#response' do
|
57
62
|
before do
|
58
63
|
stub_request(:get, retrieve_url)
|
59
64
|
.to_return(
|
60
|
-
body: {
|
65
|
+
body: {
|
66
|
+
response: { success: true, body: 'abc123' }, request: {}
|
67
|
+
}.to_json
|
61
68
|
)
|
62
|
-
|
69
|
+
promise.fetch
|
63
70
|
end
|
64
71
|
|
65
|
-
subject { response
|
66
|
-
it { is_expected.to be_a WebFetch::
|
72
|
+
subject { promise.response }
|
73
|
+
it { is_expected.to be_a WebFetch::Response }
|
67
74
|
its(:body) { is_expected.to eql 'abc123' }
|
68
75
|
end
|
69
76
|
|
70
77
|
describe '#complete?, #success?, #pending?, #error' do
|
71
|
-
before {
|
78
|
+
before { promise.fetch }
|
72
79
|
|
73
|
-
subject {
|
80
|
+
subject { promise }
|
74
81
|
|
75
82
|
context 'request succeeded' do
|
76
83
|
let(:client) { client_success }
|
@@ -106,14 +113,14 @@ RSpec.describe WebFetch::Promise do
|
|
106
113
|
end
|
107
114
|
|
108
115
|
describe '#request' do
|
109
|
-
subject {
|
116
|
+
subject { promise.request }
|
110
117
|
it { is_expected.to be_a WebFetch::Request }
|
111
118
|
its(:custom) { is_expected.to eql(my_key: 'my_value') }
|
112
119
|
end
|
113
120
|
|
114
121
|
describe '#custom' do
|
115
|
-
# I think it's good to expose this directly on the
|
116
|
-
# accessible
|
122
|
+
# I think it's good to expose this directly on the promise even though it's
|
123
|
+
# accessible as `response.request.custom`
|
117
124
|
its(:custom) { is_expected.to eql(my_key: 'my_value') }
|
118
125
|
end
|
119
126
|
end
|
data/spec/resources_spec.rb
CHANGED
@@ -11,47 +11,47 @@ describe WebFetch::Resources do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
describe '.gather' do
|
14
|
-
let(:
|
14
|
+
let(:response) do
|
15
15
|
described_class.gather(server, requests: [{ url: 'http://google.com' }])
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'provides a `gather` resource' do
|
19
|
-
expect(
|
19
|
+
expect(response[:status]).to eql 200
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'responds with hash' do
|
23
|
-
expect(
|
23
|
+
expect(response[:payload]).to be_a Hash
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
describe '.retrieve' do
|
28
28
|
it 'gives 404 not found when unrecognised uid requested' do
|
29
|
-
|
30
|
-
expect(
|
31
|
-
error =
|
29
|
+
response = described_class.retrieve(server, uid: '123')
|
30
|
+
expect(response[:status]).to eql 404
|
31
|
+
error = response[:payload][:error]
|
32
32
|
expect(error).to eql I18n.t(:uid_not_found)
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'gives 404 not found when unrecognised hash requested' do
|
36
|
-
|
37
|
-
expect(
|
38
|
-
error =
|
36
|
+
response = described_class.retrieve(server, hash: 'abc')
|
37
|
+
expect(response[:status]).to eql 404
|
38
|
+
error = response[:payload][:error]
|
39
39
|
expect(error).to eql I18n.t(:hash_not_found)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
describe '.find' do
|
44
44
|
it 'gives 404 not found when unrecognised uid requested' do
|
45
|
-
|
46
|
-
expect(
|
47
|
-
error =
|
45
|
+
response = described_class.find(server, uid: '123')
|
46
|
+
expect(response[:status]).to eql 404
|
47
|
+
error = response[:payload][:error]
|
48
48
|
expect(error).to eql I18n.t(:uid_not_found)
|
49
49
|
end
|
50
50
|
|
51
51
|
it 'gives 404 not found when unrecognised hash requested' do
|
52
|
-
|
53
|
-
expect(
|
54
|
-
error =
|
52
|
+
response = described_class.find(server, hash: 'abc')
|
53
|
+
expect(response[:status]).to eql 404
|
54
|
+
error = response[:payload][:error]
|
55
55
|
expect(error).to eql I18n.t(:hash_not_found)
|
56
56
|
end
|
57
57
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
RSpec.describe WebFetch::
|
4
|
-
let(:
|
3
|
+
RSpec.describe WebFetch::Response do
|
4
|
+
let(:response) do
|
5
5
|
described_class.new(
|
6
6
|
body: 'abc123',
|
7
7
|
headers: { 'Foo' => 'Bar' },
|
@@ -9,12 +9,13 @@ RSpec.describe WebFetch::Result do
|
|
9
9
|
pending: false,
|
10
10
|
success: false,
|
11
11
|
error: 'foo error happened',
|
12
|
+
request: { url: 'http://blah/' },
|
12
13
|
uid: 'uid123',
|
13
14
|
response_time: 123.45
|
14
15
|
)
|
15
16
|
end
|
16
17
|
|
17
|
-
subject {
|
18
|
+
subject { response }
|
18
19
|
|
19
20
|
it { is_expected.to be_a described_class }
|
20
21
|
its(:body) { is_expected.to eql 'abc123' }
|
@@ -26,4 +27,10 @@ RSpec.describe WebFetch::Result do
|
|
26
27
|
its(:error) { is_expected.to eql 'foo error happened' }
|
27
28
|
its(:uid) { is_expected.to eql 'uid123' }
|
28
29
|
its(:response_time) { is_expected.to eql 123.45 }
|
30
|
+
its(:request) { is_expected.to be_a WebFetch::Request }
|
31
|
+
|
32
|
+
describe '#request' do
|
33
|
+
subject { response.request }
|
34
|
+
its(:url) { is_expected.to eql 'http://blah/' }
|
35
|
+
end
|
29
36
|
end
|
data/spec/router_spec.rb
CHANGED
@@ -38,11 +38,11 @@ describe WebFetch::Router do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'returns appropriate response when invaid json provided' do
|
41
|
-
|
41
|
+
response = router.route('/gather',
|
42
42
|
method: 'POST',
|
43
43
|
query_string: 'json=uh oh :(',
|
44
44
|
server: nil)
|
45
|
-
expect(
|
45
|
+
expect(response).to eql(status: 400, payload: I18n.t(:bad_json))
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
data/web_fetch.gemspec
CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.add_dependency 'subprocess', '~> 1.3'
|
35
35
|
|
36
36
|
s.add_development_dependency 'byebug', '~> 9.0'
|
37
|
+
s.add_development_dependency 'rake', '~> 12.3'
|
37
38
|
s.add_development_dependency 'rspec', '~> 3.5'
|
38
39
|
s.add_development_dependency 'rspec-its', '~> 1.2'
|
39
40
|
s.add_development_dependency 'rubocop', '~> 0.59.2'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: web_fetch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Farrell
|
@@ -192,6 +192,20 @@ dependencies:
|
|
192
192
|
- - "~>"
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '9.0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: rake
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '12.3'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '12.3'
|
195
209
|
- !ruby/object:Gem::Dependency
|
196
210
|
name: rspec
|
197
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -262,7 +276,9 @@ files:
|
|
262
276
|
- ".ruby-version"
|
263
277
|
- Gemfile
|
264
278
|
- LICENSE
|
279
|
+
- Makefile
|
265
280
|
- README.md
|
281
|
+
- Rakefile
|
266
282
|
- TODO
|
267
283
|
- bin/rspec
|
268
284
|
- bin/rubocop
|
@@ -287,7 +303,7 @@ files:
|
|
287
303
|
- lib/web_fetch/promise.rb
|
288
304
|
- lib/web_fetch/request.rb
|
289
305
|
- lib/web_fetch/resources.rb
|
290
|
-
- lib/web_fetch/
|
306
|
+
- lib/web_fetch/response.rb
|
291
307
|
- lib/web_fetch/retriever.rb
|
292
308
|
- lib/web_fetch/router.rb
|
293
309
|
- lib/web_fetch/server.rb
|
@@ -302,7 +318,7 @@ files:
|
|
302
318
|
- spec/promise_spec.rb
|
303
319
|
- spec/request_spec.rb
|
304
320
|
- spec/resources_spec.rb
|
305
|
-
- spec/
|
321
|
+
- spec/response_spec.rb
|
306
322
|
- spec/retriever_spec.rb
|
307
323
|
- spec/router_spec.rb
|
308
324
|
- spec/server_spec.rb
|