resync-client 0.1.2 → 0.2.1

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGES.md +10 -0
  4. data/lib/resync/client.rb +63 -0
  5. data/lib/resync/client/http_helper.rb +90 -90
  6. data/lib/resync/client/mixins.rb +1 -0
  7. data/lib/resync/client/mixins/bitstream_resource.rb +26 -0
  8. data/lib/resync/client/mixins/bitstream_resource_list.rb +29 -0
  9. data/lib/resync/client/mixins/client_delegator.rb +38 -0
  10. data/lib/resync/client/mixins/downloadable.rb +36 -0
  11. data/lib/resync/client/mixins/link_client_delegate.rb +19 -0
  12. data/lib/resync/client/mixins/resource_client_delegate.rb +19 -0
  13. data/lib/resync/client/mixins/zipped_resource.rb +20 -0
  14. data/lib/resync/client/mixins/zipped_resource_list.rb +26 -0
  15. data/lib/resync/client/version.rb +1 -1
  16. data/lib/resync/client/zip.rb +1 -0
  17. data/lib/resync/client/zip/bitstream.rb +85 -0
  18. data/lib/resync/client/zip/zip_package.rb +78 -0
  19. data/lib/resync/client/zip/zip_packages.rb +59 -0
  20. data/lib/resync/extensions.rb +36 -0
  21. data/resync-client.gemspec +1 -1
  22. data/spec/acceptance/example_spec.rb +46 -0
  23. data/spec/data/resourcedump/changedump.xml +16 -0
  24. data/spec/data/simulator/capability-list.xml +2 -0
  25. data/spec/data/simulator/change-list.xml +2 -0
  26. data/spec/data/simulator/source-description.xml +2 -0
  27. data/spec/data/simulator/update.txt +1 -0
  28. data/spec/unit/resync/client/bitstream_spec.rb +84 -80
  29. data/spec/unit/resync/client/client_spec.rb +64 -3
  30. data/spec/unit/resync/client/{resync_extensions_spec.rb → extensions_spec.rb} +1 -6
  31. data/spec/unit/resync/client/http_helper_spec.rb +187 -185
  32. data/spec/unit/resync/client/zip_package_spec.rb +47 -32
  33. data/spec/unit/resync/client/zip_packages_spec.rb +42 -38
  34. data/spec/unit/resync/client/zipped_resource_list_spec.rb +61 -0
  35. metadata +35 -16
  36. data/lib/resync/client/bitstream.rb +0 -79
  37. data/lib/resync/client/client.rb +0 -58
  38. data/lib/resync/client/downloadable.rb +0 -35
  39. data/lib/resync/client/dump.rb +0 -26
  40. data/lib/resync/client/resync_extensions.rb +0 -85
  41. data/lib/resync/client/zip_package.rb +0 -66
  42. data/lib/resync/client/zip_packages.rb +0 -51
  43. data/spec/unit/resync/client/dump_spec.rb +0 -26
@@ -3,17 +3,21 @@ require 'spec_helper'
3
3
  module Resync
4
4
  describe Client do
5
5
  before(:each) do
6
- @helper = instance_double(HTTPHelper)
6
+ @helper = instance_double(Client::HTTPHelper)
7
7
  @client = Client.new(helper: @helper)
8
8
  end
9
9
 
10
- describe '#get' do
10
+ describe '#get_and_parse' do
11
11
  it 'retrieves a CapabilityList' do
12
12
  uri = URI('http://example.org/capability-list.xml')
13
13
  data = File.read('spec/data/examples/capability-list.xml')
14
14
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
15
15
  doc = @client.get_and_parse(uri)
16
16
  expect(doc).to be_a(Resync::CapabilityList)
17
+ doc.resources.each do |r|
18
+ expect(r.client_delegate).to be(doc)
19
+ expect(r.client).to be(@client)
20
+ end
17
21
  end
18
22
 
19
23
  it 'retrieves a ChangeDump' do
@@ -22,6 +26,10 @@ module Resync
22
26
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
23
27
  doc = @client.get_and_parse(uri)
24
28
  expect(doc).to be_a(Resync::ChangeDump)
29
+ doc.resources.each do |r|
30
+ expect(r.client_delegate).to be(doc)
31
+ expect(r.client).to be(@client)
32
+ end
25
33
  end
26
34
 
27
35
  it 'retrieves a ChangeDumpManifest' do
@@ -30,6 +38,10 @@ module Resync
30
38
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
31
39
  doc = @client.get_and_parse(uri)
32
40
  expect(doc).to be_a(Resync::ChangeDumpManifest)
41
+ doc.resources.each do |r|
42
+ expect(r.client_delegate).to be(doc)
43
+ expect(r.client).to be(@client)
44
+ end
33
45
  end
34
46
 
35
47
  it 'retrieves a ChangeList' do
@@ -38,6 +50,10 @@ module Resync
38
50
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
39
51
  doc = @client.get_and_parse(uri)
40
52
  expect(doc).to be_a(Resync::ChangeList)
53
+ doc.resources.each do |r|
54
+ expect(r.client_delegate).to be(doc)
55
+ expect(r.client).to be(@client)
56
+ end
41
57
  end
42
58
 
43
59
  it 'retrieves a ResourceDump' do
@@ -46,6 +62,10 @@ module Resync
46
62
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
47
63
  doc = @client.get_and_parse(uri)
48
64
  expect(doc).to be_a(Resync::ResourceDump)
65
+ doc.resources.each do |r|
66
+ expect(r.client_delegate).to be(doc)
67
+ expect(r.client).to be(@client)
68
+ end
49
69
  end
50
70
 
51
71
  it 'retrieves a ResourceDumpManifest' do
@@ -54,6 +74,10 @@ module Resync
54
74
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
55
75
  doc = @client.get_and_parse(uri)
56
76
  expect(doc).to be_a(Resync::ResourceDumpManifest)
77
+ doc.resources.each do |r|
78
+ expect(r.client_delegate).to be(doc)
79
+ expect(r.client).to be(@client)
80
+ end
57
81
  end
58
82
 
59
83
  it 'retrieves a ResourceList' do
@@ -62,6 +86,10 @@ module Resync
62
86
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
63
87
  doc = @client.get_and_parse(uri)
64
88
  expect(doc).to be_a(Resync::ResourceList)
89
+ doc.resources.each do |r|
90
+ expect(r.client_delegate).to be(doc)
91
+ expect(r.client).to be(@client)
92
+ end
65
93
  end
66
94
 
67
95
  it 'retrieves a SourceDescription' do
@@ -70,6 +98,10 @@ module Resync
70
98
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
71
99
  doc = @client.get_and_parse(uri)
72
100
  expect(doc).to be_a(Resync::SourceDescription)
101
+ doc.resources.each do |r|
102
+ expect(r.client_delegate).to be(doc)
103
+ expect(r.client).to be(@client)
104
+ end
73
105
  end
74
106
 
75
107
  it 'retrieves a ChangeListIndex' do
@@ -78,6 +110,10 @@ module Resync
78
110
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
79
111
  doc = @client.get_and_parse(uri)
80
112
  expect(doc).to be_a(Resync::ChangeListIndex)
113
+ doc.resources.each do |r|
114
+ expect(r.client_delegate).to be(doc)
115
+ expect(r.client).to be(@client)
116
+ end
81
117
  end
82
118
 
83
119
  it 'retrieves a ResourceListIndex' do
@@ -86,6 +122,10 @@ module Resync
86
122
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
87
123
  doc = @client.get_and_parse(uri)
88
124
  expect(doc).to be_a(Resync::ResourceListIndex)
125
+ doc.resources.each do |r|
126
+ expect(r.client_delegate).to be(doc)
127
+ expect(r.client).to be(@client)
128
+ end
89
129
  end
90
130
 
91
131
  it 'injects the client into the returned document' do
@@ -94,6 +134,27 @@ module Resync
94
134
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
95
135
  doc = @client.get_and_parse(uri)
96
136
  expect(doc.client).to be(@client)
137
+ doc.resources.each do |r|
138
+ expect(r.client_delegate).to be(doc)
139
+ expect(r.client).to be(@client)
140
+ end
141
+ end
142
+
143
+ it 'injects the client recursively' do
144
+ uri = URI('http://example.org/resource-list-index.xml')
145
+ data = File.read('spec/data/examples/resource-list-index.xml')
146
+ resource_list_xml = File.read('spec/data/examples/resource-list.xml')
147
+ expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
148
+ doc = @client.get_and_parse(uri)
149
+ doc.resources.each do |r|
150
+ expect(r.client).to be(@client)
151
+ expect(@helper).to receive(:fetch).with(uri: r.uri).and_return(resource_list_xml)
152
+ resource_doc = r.get_and_parse
153
+ expect(resource_doc.client).to be(@client)
154
+ resource_doc.resources.each do |r2|
155
+ expect(r2.client).to be(@client)
156
+ end
157
+ end
97
158
  end
98
159
  end
99
160
 
@@ -101,7 +162,7 @@ module Resync
101
162
  it 'creates its own connection if none is provided' do
102
163
  uri = URI('http://example.org/capability-list.xml')
103
164
  data = File.read('spec/data/examples/capability-list.xml')
104
- expect(HTTPHelper).to receive(:new).and_return(@helper)
165
+ expect(Client::HTTPHelper).to receive(:new).and_return(@helper)
105
166
  expect(@helper).to receive(:fetch).with(uri: uri).and_return(data)
106
167
  client = Client.new
107
168
  client.get_and_parse(uri)
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module Resync
4
+
4
5
  describe 'extensions' do
5
6
 
6
7
  # ------------------------------------------------------------
@@ -53,12 +54,6 @@ module Resync
53
54
  expect(l.client).to be(client2)
54
55
  end
55
56
  end
56
-
57
- it 'defaults to a new client' do
58
- client = instance_double(Resync::Client)
59
- expect(Resync::Client).to receive(:new) { client }
60
- expect(@list.client).to be(client)
61
- end
62
57
  end
63
58
 
64
59
  describe Resource do
@@ -1,235 +1,237 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module Resync
4
- describe HTTPHelper do
4
+ class Client # rubocop:disable Metrics/ClassLength
5
+ describe HTTPHelper do
5
6
 
6
- # ------------------------------------------------------------
7
- # Fixture
8
-
9
- attr_writer :user_agent
10
-
11
- def user_agent
12
- @user_agent ||= 'elvis'
13
- end
14
-
15
- attr_writer :helper
16
-
17
- def helper
18
- @helper ||= HTTPHelper.new(user_agent: user_agent)
19
- end
7
+ # ------------------------------------------------------------
8
+ # Fixture
20
9
 
21
- # ------------------------------------------------------------
22
- # Tests
10
+ attr_writer :user_agent
23
11
 
24
- describe '#fetch' do
12
+ def user_agent
13
+ @user_agent ||= 'elvis'
14
+ end
25
15
 
26
- # ------------------------------
27
- # Fixture
16
+ attr_writer :helper
28
17
 
29
- before(:each) do
30
- @http = instance_double(Net::HTTP)
31
- allow(Net::HTTP).to receive(:new).and_return(@http)
32
- allow(@http).to receive(:start).and_yield(@http)
33
- @success = Net::HTTPOK.allocate
34
- @body = 'I am the body of the response'
35
- allow(@success).to receive(:body).and_return(@body)
18
+ def helper
19
+ @helper ||= HTTPHelper.new(user_agent: user_agent)
36
20
  end
37
21
 
38
- # ------------------------------
22
+ # ------------------------------------------------------------
39
23
  # Tests
40
24
 
41
- it 'requests the specified URI' do
42
- uri = URI('http://example.org/')
43
- expect(@http).to receive(:request).with(request_for(uri: uri)).and_yield(@success)
44
- helper.fetch(uri: uri)
45
- end
25
+ describe '#fetch' do
46
26
 
47
- it 'gets a response' do
48
- expect(@http).to receive(:request).and_yield(@success)
49
- expect(helper.fetch(uri: URI('http://example.org/'))).to be(@body)
50
- end
27
+ # ------------------------------
28
+ # Fixture
51
29
 
52
- it 'sets the User-Agent header' do
53
- agent = 'Not Elvis'
54
- helper = HTTPHelper.new(user_agent: agent)
55
- expect(@http).to receive(:request).with(request_for(headers: { 'User-Agent' => agent })).and_yield(@success)
56
- helper.fetch(uri: URI('http://example.org/'))
57
- end
30
+ before(:each) do
31
+ @http = instance_double(Net::HTTP)
32
+ allow(Net::HTTP).to receive(:new).and_return(@http)
33
+ allow(@http).to receive(:start).and_yield(@http)
34
+ @success = Net::HTTPOK.allocate
35
+ @body = 'I am the body of the response'
36
+ allow(@success).to receive(:body).and_return(@body)
37
+ end
58
38
 
59
- it 'uses SSL for https requests' do
60
- uri = URI('https://example.org/')
61
- expect(Net::HTTP).to receive(:start).with(uri.hostname, uri.port, use_ssl: true).and_call_original
62
- expect(@http).to receive(:request).and_yield(@success)
63
- helper.fetch(uri: uri)
64
- end
39
+ # ------------------------------
40
+ # Tests
65
41
 
66
- it 're-requests on receiving a 1xx' do
67
- uri = URI('http://example.org/')
68
- @info = Net::HTTPContinue.allocate
42
+ it 'requests the specified URI' do
43
+ uri = URI('http://example.org/')
44
+ expect(@http).to receive(:request).with(request_for(uri: uri)).and_yield(@success)
45
+ helper.fetch(uri: uri)
46
+ end
69
47
 
70
- expected = [@info, @success]
71
- expect(@http).to receive(:request).twice.with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })) do |&block|
72
- block.call(expected.shift)
48
+ it 'gets a response' do
49
+ expect(@http).to receive(:request).and_yield(@success)
50
+ expect(helper.fetch(uri: URI('http://example.org/'))).to be(@body)
73
51
  end
74
52
 
75
- expect(helper.fetch(uri: uri)).to be(@body)
76
- end
53
+ it 'sets the User-Agent header' do
54
+ agent = 'Not Elvis'
55
+ helper = HTTPHelper.new(user_agent: agent)
56
+ expect(@http).to receive(:request).with(request_for(headers: { 'User-Agent' => agent })).and_yield(@success)
57
+ helper.fetch(uri: URI('http://example.org/'))
58
+ end
77
59
 
78
- it 'redirects on receiving a 3xx' do
79
- uri = URI('http://example.org/')
80
- uri2 = URI('http://example.org/new')
81
- @redirect = Net::HTTPMovedPermanently.allocate
82
- allow(@redirect).to receive(:[]).with('location').and_return(uri2.to_s)
83
- expect(@http).to receive(:request).with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })).and_yield(@redirect)
84
- expect(@http).to receive(:request).with(request_for(uri: uri2, headers: { 'User-Agent' => user_agent })).and_yield(@success)
85
- expect(helper.fetch(uri: uri)).to be(@body)
86
- end
60
+ it 'uses SSL for https requests' do
61
+ uri = URI('https://example.org/')
62
+ expect(Net::HTTP).to receive(:start).with(uri.hostname, uri.port, use_ssl: true).and_call_original
63
+ expect(@http).to receive(:request).and_yield(@success)
64
+ helper.fetch(uri: uri)
65
+ end
87
66
 
88
- it 'only redirects a limited number of times' do
89
- uri = URI('http://example.org/')
90
- @redirect = Net::HTTPMovedPermanently.allocate
91
- allow(@redirect).to receive(:[]).with('location').and_return(uri.to_s)
92
- expect(@http).to receive(:request).with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })).exactly(HTTPHelper::DEFAULT_MAX_REDIRECTS).times.and_yield(@redirect)
93
- expect { helper.fetch(uri: uri) }.to raise_error
94
- end
67
+ it 're-requests on receiving a 1xx' do
68
+ uri = URI('http://example.org/')
69
+ @info = Net::HTTPContinue.allocate
95
70
 
96
- it 'fails on a 4xx' do
97
- @error = Net::HTTPForbidden
98
- allow(@error).to receive(:code).and_return(403)
99
- allow(@error).to receive(:message).and_return('Forbidden')
100
- expect(@http).to receive(:request).and_yield(@error)
101
- uri = URI('http://example.org/')
102
- expect { helper.fetch(uri: uri) }.to raise_error
103
- end
71
+ expected = [@info, @success]
72
+ expect(@http).to receive(:request).twice.with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })) do |&block|
73
+ block.call(expected.shift)
74
+ end
104
75
 
105
- it 'fails on a 5xx' do
106
- @error = Net::HTTPServerError
107
- allow(@error).to receive(:code).and_return(500)
108
- allow(@error).to receive(:message).and_return('Internal Server Error')
109
- expect(@http).to receive(:request).and_yield(@error)
110
- uri = URI('http://example.org/')
111
- expect { helper.fetch(uri: uri) }.to raise_error
112
- end
113
- end
76
+ expect(helper.fetch(uri: uri)).to be(@body)
77
+ end
114
78
 
115
- describe '#fetch_to_file' do
79
+ it 'redirects on receiving a 3xx' do
80
+ uri = URI('http://example.org/')
81
+ uri2 = URI('http://example.org/new')
82
+ @redirect = Net::HTTPMovedPermanently.allocate
83
+ allow(@redirect).to receive(:[]).with('location').and_return(uri2.to_s)
84
+ expect(@http).to receive(:request).with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })).and_yield(@redirect)
85
+ expect(@http).to receive(:request).with(request_for(uri: uri2, headers: { 'User-Agent' => user_agent })).and_yield(@success)
86
+ expect(helper.fetch(uri: uri)).to be(@body)
87
+ end
116
88
 
117
- # ------------------------------
118
- # Fixture
89
+ it 'only redirects a limited number of times' do
90
+ uri = URI('http://example.org/')
91
+ @redirect = Net::HTTPMovedPermanently.allocate
92
+ allow(@redirect).to receive(:[]).with('location').and_return(uri.to_s)
93
+ expect(@http).to receive(:request).with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })).exactly(HTTPHelper::DEFAULT_MAX_REDIRECTS).times.and_yield(@redirect)
94
+ expect { helper.fetch(uri: uri) }.to raise_error
95
+ end
119
96
 
120
- before(:each) do
121
- @path = nil
122
- @http = instance_double(Net::HTTP)
123
- allow(Net::HTTP).to receive(:new).and_return(@http)
124
- allow(@http).to receive(:start).and_yield(@http)
97
+ it 'fails on a 4xx' do
98
+ @error = Net::HTTPForbidden
99
+ allow(@error).to receive(:code).and_return(403)
100
+ allow(@error).to receive(:message).and_return('Forbidden')
101
+ expect(@http).to receive(:request).and_yield(@error)
102
+ uri = URI('http://example.org/')
103
+ expect { helper.fetch(uri: uri) }.to raise_error
104
+ end
125
105
 
126
- @data = (0...100).map { ('a'..'z').to_a[rand(26)] }.join
127
- @success = Net::HTTPOK.allocate
128
- allow(@success).to receive(:[]).with('Content-Type').and_return('text/plain')
129
- stub = allow(@success).to receive(:read_body)
130
- (0...10).each do |i|
131
- chunk = @data[10 * i, 10]
132
- stub = stub.and_yield(chunk)
106
+ it 'fails on a 5xx' do
107
+ @error = Net::HTTPServerError
108
+ allow(@error).to receive(:code).and_return(500)
109
+ allow(@error).to receive(:message).and_return('Internal Server Error')
110
+ expect(@http).to receive(:request).and_yield(@error)
111
+ uri = URI('http://example.org/')
112
+ expect { helper.fetch(uri: uri) }.to raise_error
133
113
  end
134
114
  end
135
115
 
136
- after(:each) do
137
- File.delete(@path) if @path
138
- end
116
+ describe '#fetch_to_file' do
139
117
 
140
- # ------------------------------
141
- # Tests
118
+ # ------------------------------
119
+ # Fixture
142
120
 
143
- it 'requests the specified URI' do
144
- uri = URI('http://example.org/')
145
- expect(@http).to receive(:request).with(request_for(uri: uri)).and_yield(@success)
146
- @path = helper.fetch_to_file(uri: uri)
147
- end
121
+ before(:each) do
122
+ @path = nil
123
+ @http = instance_double(Net::HTTP)
124
+ allow(Net::HTTP).to receive(:new).and_return(@http)
125
+ allow(@http).to receive(:start).and_yield(@http)
148
126
 
149
- it 'returns the path to a file containing the response' do
150
- uri = URI('http://example.org/')
151
- expect(@http).to receive(:request).with(request_for(uri: uri)).and_yield(@success)
152
- @path = helper.fetch_to_file(uri: uri)
153
- expect(File.read(@path)).to eq(@data)
154
- end
127
+ @data = (0...100).map { ('a'..'z').to_a[rand(26)] }.join
128
+ @success = Net::HTTPOK.allocate
129
+ allow(@success).to receive(:[]).with('Content-Type').and_return('text/plain')
130
+ stub = allow(@success).to receive(:read_body)
131
+ (0...10).each do |i|
132
+ chunk = @data[10 * i, 10]
133
+ stub = stub.and_yield(chunk)
134
+ end
135
+ end
155
136
 
156
- it 'sets the User-Agent header' do
157
- agent = 'Not Elvis'
158
- helper = HTTPHelper.new(user_agent: agent)
159
- expect(@http).to receive(:request).with(request_for(headers: { 'User-Agent' => agent })).and_yield(@success)
160
- @path = helper.fetch_to_file(uri: URI('http://example.org/'))
161
- end
137
+ after(:each) do
138
+ File.delete(@path) if @path
139
+ end
162
140
 
163
- it 'uses SSL for https requests' do
164
- uri = URI('https://example.org/')
165
- expect(Net::HTTP).to receive(:start).with(uri.hostname, uri.port, use_ssl: true).and_call_original
166
- expect(@http).to receive(:request).and_yield(@success)
167
- @path = helper.fetch_to_file(uri: uri)
168
- end
141
+ # ------------------------------
142
+ # Tests
169
143
 
170
- it 're-requests on receiving a 1xx' do
171
- uri = URI('http://example.org/')
172
- @info = Net::HTTPContinue.allocate
144
+ it 'requests the specified URI' do
145
+ uri = URI('http://example.org/')
146
+ expect(@http).to receive(:request).with(request_for(uri: uri)).and_yield(@success)
147
+ @path = helper.fetch_to_file(uri: uri)
148
+ end
173
149
 
174
- expected = [@info, @success]
175
- expect(@http).to receive(:request).twice.with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })) do |&block|
176
- block.call(expected.shift)
150
+ it 'returns the path to a file containing the response' do
151
+ uri = URI('http://example.org/')
152
+ expect(@http).to receive(:request).with(request_for(uri: uri)).and_yield(@success)
153
+ @path = helper.fetch_to_file(uri: uri)
154
+ expect(File.read(@path)).to eq(@data)
177
155
  end
178
156
 
179
- @path = helper.fetch_to_file(uri: uri)
180
- expect(File.read(@path)).to eq(@data)
181
- end
157
+ it 'sets the User-Agent header' do
158
+ agent = 'Not Elvis'
159
+ helper = HTTPHelper.new(user_agent: agent)
160
+ expect(@http).to receive(:request).with(request_for(headers: { 'User-Agent' => agent })).and_yield(@success)
161
+ @path = helper.fetch_to_file(uri: URI('http://example.org/'))
162
+ end
182
163
 
183
- it 'redirects on receiving a 3xx' do
184
- uri = URI('http://example.org/')
185
- uri2 = URI('http://example.org/new')
186
- @redirect = Net::HTTPMovedPermanently.allocate
187
- allow(@redirect).to receive(:[]).with('location').and_return(uri2.to_s)
188
- expect(@http).to receive(:request).with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })).and_yield(@redirect)
189
- expect(@http).to receive(:request).with(request_for(uri: uri2, headers: { 'User-Agent' => user_agent })).and_yield(@success)
190
- @path = helper.fetch_to_file(uri: uri)
191
- expect(File.read(@path)).to eq(@data)
192
- end
164
+ it 'uses SSL for https requests' do
165
+ uri = URI('https://example.org/')
166
+ expect(Net::HTTP).to receive(:start).with(uri.hostname, uri.port, use_ssl: true).and_call_original
167
+ expect(@http).to receive(:request).and_yield(@success)
168
+ @path = helper.fetch_to_file(uri: uri)
169
+ end
193
170
 
194
- it 'only redirects a limited number of times' do
195
- uri = URI('http://example.org/')
196
- @redirect = Net::HTTPMovedPermanently.allocate
197
- allow(@redirect).to receive(:[]).with('location').and_return(uri.to_s)
198
- expect(@http).to receive(:request).with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })).exactly(HTTPHelper::DEFAULT_MAX_REDIRECTS).times.and_yield(@redirect)
199
- expect { @path = helper.fetch_to_file(uri: uri) }.to raise_error
200
- expect(@path).to be_nil
201
- end
171
+ it 're-requests on receiving a 1xx' do
172
+ uri = URI('http://example.org/')
173
+ @info = Net::HTTPContinue.allocate
202
174
 
203
- it 'fails on a 4xx' do
204
- @error = Net::HTTPForbidden
205
- allow(@error).to receive(:code).and_return(403)
206
- allow(@error).to receive(:message).and_return('Forbidden')
207
- expect(@http).to receive(:request).and_yield(@error)
208
- uri = URI('http://example.org/')
209
- expect { @path = helper.fetch_to_file(uri: uri) }.to raise_error
210
- expect(@path).to be_nil
211
- end
175
+ expected = [@info, @success]
176
+ expect(@http).to receive(:request).twice.with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })) do |&block|
177
+ block.call(expected.shift)
178
+ end
212
179
 
213
- it 'fails on a 5xx' do
214
- @error = Net::HTTPServerError
215
- allow(@error).to receive(:code).and_return(500)
216
- allow(@error).to receive(:message).and_return('Internal Server Error')
217
- expect(@http).to receive(:request).and_yield(@error)
218
- uri = URI('http://example.org/')
219
- expect { helper.fetch_to_file(uri: uri) }.to raise_error
220
- end
180
+ @path = helper.fetch_to_file(uri: uri)
181
+ expect(File.read(@path)).to eq(@data)
182
+ end
221
183
 
222
- it 'accepts a file path argument' do
223
- Dir.mktmpdir do |dir|
224
- expect(Dir.exist?(dir)).to be(true)
225
- path = "#{dir}/http_helper_spec.out"
184
+ it 'redirects on receiving a 3xx' do
226
185
  uri = URI('http://example.org/')
227
- expect(@http).to receive(:request).with(request_for(uri: uri)).and_yield(@success)
228
- helper.fetch_to_file(uri: uri, path: path)
229
- expect(File.read(path)).to eq(@data)
186
+ uri2 = URI('http://example.org/new')
187
+ @redirect = Net::HTTPMovedPermanently.allocate
188
+ allow(@redirect).to receive(:[]).with('location').and_return(uri2.to_s)
189
+ expect(@http).to receive(:request).with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })).and_yield(@redirect)
190
+ expect(@http).to receive(:request).with(request_for(uri: uri2, headers: { 'User-Agent' => user_agent })).and_yield(@success)
191
+ @path = helper.fetch_to_file(uri: uri)
192
+ expect(File.read(@path)).to eq(@data)
193
+ end
194
+
195
+ it 'only redirects a limited number of times' do
196
+ uri = URI('http://example.org/')
197
+ @redirect = Net::HTTPMovedPermanently.allocate
198
+ allow(@redirect).to receive(:[]).with('location').and_return(uri.to_s)
199
+ expect(@http).to receive(:request).with(request_for(uri: uri, headers: { 'User-Agent' => user_agent })).exactly(HTTPHelper::DEFAULT_MAX_REDIRECTS).times.and_yield(@redirect)
200
+ expect { @path = helper.fetch_to_file(uri: uri) }.to raise_error
201
+ expect(@path).to be_nil
202
+ end
203
+
204
+ it 'fails on a 4xx' do
205
+ @error = Net::HTTPForbidden
206
+ allow(@error).to receive(:code).and_return(403)
207
+ allow(@error).to receive(:message).and_return('Forbidden')
208
+ expect(@http).to receive(:request).and_yield(@error)
209
+ uri = URI('http://example.org/')
210
+ expect { @path = helper.fetch_to_file(uri: uri) }.to raise_error
211
+ expect(@path).to be_nil
212
+ end
213
+
214
+ it 'fails on a 5xx' do
215
+ @error = Net::HTTPServerError
216
+ allow(@error).to receive(:code).and_return(500)
217
+ allow(@error).to receive(:message).and_return('Internal Server Error')
218
+ expect(@http).to receive(:request).and_yield(@error)
219
+ uri = URI('http://example.org/')
220
+ expect { helper.fetch_to_file(uri: uri) }.to raise_error
221
+ end
222
+
223
+ it 'accepts a file path argument' do
224
+ Dir.mktmpdir do |dir|
225
+ expect(Dir.exist?(dir)).to be(true)
226
+ path = "#{dir}/http_helper_spec.out"
227
+ uri = URI('http://example.org/')
228
+ expect(@http).to receive(:request).with(request_for(uri: uri)).and_yield(@success)
229
+ helper.fetch_to_file(uri: uri, path: path)
230
+ expect(File.read(path)).to eq(@data)
231
+ end
230
232
  end
231
233
  end
232
- end
233
234
 
235
+ end
234
236
  end
235
237
  end