resourceful 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +21 -0
- data/README.markdown +86 -0
- data/Rakefile +89 -0
- data/lib/resourceful.rb +28 -0
- data/lib/resourceful/authentication_manager.rb +85 -0
- data/lib/resourceful/cache_manager.rb +160 -0
- data/lib/resourceful/header.rb +31 -0
- data/lib/resourceful/http_accessor.rb +79 -0
- data/lib/resourceful/net_http_adapter.rb +57 -0
- data/lib/resourceful/options_interpreter.rb +78 -0
- data/lib/resourceful/request.rb +64 -0
- data/lib/resourceful/resource.rb +216 -0
- data/lib/resourceful/response.rb +100 -0
- data/lib/resourceful/stubbed_resource_proxy.rb +47 -0
- data/lib/resourceful/util.rb +6 -0
- data/lib/resourceful/version.rb +1 -0
- data/spec/acceptance_shared_specs.rb +49 -0
- data/spec/acceptance_spec.rb +344 -0
- data/spec/resourceful/authentication_manager_spec.rb +204 -0
- data/spec/resourceful/cache_manager_spec.rb +202 -0
- data/spec/resourceful/header_spec.rb +38 -0
- data/spec/resourceful/http_accessor_spec.rb +120 -0
- data/spec/resourceful/net_http_adapter_spec.rb +90 -0
- data/spec/resourceful/options_interpreter_spec.rb +94 -0
- data/spec/resourceful/request_spec.rb +261 -0
- data/spec/resourceful/resource_spec.rb +481 -0
- data/spec/resourceful/response_spec.rb +199 -0
- data/spec/resourceful/stubbed_resource_proxy_spec.rb +58 -0
- data/spec/simple_http_server_shared_spec.rb +151 -0
- data/spec/simple_http_server_shared_spec_spec.rb +195 -0
- data/spec/spec_helper.rb +12 -0
- metadata +129 -0
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname(__FILE__).dirname + '../spec_helper'
|
3
|
+
|
4
|
+
require 'resourceful/authentication_manager'
|
5
|
+
|
6
|
+
describe Resourceful::AuthenticationManager do
|
7
|
+
|
8
|
+
before do
|
9
|
+
@authmgr = Resourceful::AuthenticationManager.new
|
10
|
+
|
11
|
+
@authenticator = mock('Authenticator')
|
12
|
+
end
|
13
|
+
|
14
|
+
[:add_auth_handler, :associate_auth_info, :add_credentials].each do |meth|
|
15
|
+
it "should have ##{meth}" do
|
16
|
+
@authmgr.should respond_to(meth)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should add an authenticator to its list' do
|
21
|
+
@authmgr.add_auth_handler(@authenticator)
|
22
|
+
@authmgr.instance_variable_get("@authenticators").should include(@authenticator)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'associating authenticators with challanges' do
|
26
|
+
before do
|
27
|
+
@authmgr.add_auth_handler(@authenticator)
|
28
|
+
@authenticator.stub!(:valid_for?).and_return(true)
|
29
|
+
@authenticator.stub!(:update_credentials)
|
30
|
+
@challenge = mock('Response')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should check that an authenticator is valid for a challenge' do
|
34
|
+
@authenticator.should_receive(:valid_for?).with(@challenge).and_return(true)
|
35
|
+
@authmgr.associate_auth_info(@challenge)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should update the credentials of the authenticator if it is valid for the challenge' do
|
39
|
+
@authenticator.should_receive(:update_credentials).with(@challenge)
|
40
|
+
@authmgr.associate_auth_info(@challenge)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should not update the credentials of the authenticator if it is not valid for the challenge' do
|
44
|
+
@authenticator.stub!(:valid_for?).and_return(false)
|
45
|
+
@authenticator.should_not_receive(:update_credentials).with(@challenge)
|
46
|
+
@authmgr.associate_auth_info(@challenge)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'adding credentials to a request' do
|
52
|
+
before do
|
53
|
+
@authmgr.add_auth_handler(@authenticator)
|
54
|
+
@authenticator.stub!(:can_handle?).and_return(true)
|
55
|
+
@authenticator.stub!(:add_credentials_to)
|
56
|
+
@request = mock('Request')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should find an authenticator that can handle the request' do
|
60
|
+
@authenticator.should_receive(:can_handle?).with(@request).and_return(true)
|
61
|
+
@authmgr.add_credentials(@request)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should add the authenticators credentials to the request' do
|
65
|
+
@authenticator.should_receive(:add_credentials_to).with(@request)
|
66
|
+
@authmgr.add_credentials(@request)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should not add the authenticators credentials to the request if it cant handle it' do
|
70
|
+
@authenticator.should_receive(:can_handle?).with(@request).and_return(false)
|
71
|
+
@authenticator.should_not_receive(:add_credentials_to).with(@request)
|
72
|
+
@authmgr.add_credentials(@request)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe Resourceful::BasicAuthenticator do
|
80
|
+
before do
|
81
|
+
@auth = Resourceful::BasicAuthenticator.new('Test Auth', 'admin', 'secret')
|
82
|
+
end
|
83
|
+
|
84
|
+
{:realm => 'Test Auth', :username => 'admin', :password => 'secret'}.each do |meth,val|
|
85
|
+
it "should initialize with a #{meth}" do
|
86
|
+
@auth.instance_variable_get("@#{meth}").should == val
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "Updating from a challenge response" do
|
91
|
+
before do
|
92
|
+
@header = {'WWW-Authenticate' => ['Basic realm="Test Auth"']}
|
93
|
+
@chal = mock('response', :header => @header, :uri => 'http://example.com/foo/bar')
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should be valid for a challenge response with scheme "Basic" and the same realm' do
|
97
|
+
@auth.valid_for?(@chal).should be_true
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should be valid for a challenge response with multiple schemes including matchin "Basic" challenge' do
|
101
|
+
@header = {'WWW-Authenticate' => ['Digest some other stuff', 'Basic realm="Test Auth"', 'Weird scheme']}
|
102
|
+
|
103
|
+
@auth.valid_for?(@chal).should be_true
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should not be sensitive to case variances in the scheme' do
|
107
|
+
@header['WWW-Authenticate'] = ['bAsIc realm="Test Auth"']
|
108
|
+
@auth.valid_for?(@chal).should be_true
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should not be sensitive to case variances in the realm directive' do
|
112
|
+
@header['WWW-Authenticate'] = ['Basic rEaLm="Test Auth"']
|
113
|
+
@auth.valid_for?(@chal).should be_true
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should not be sensitive to case variances in the realm value' do
|
117
|
+
@header['WWW-Authenticate'] = ['Basic realm="test auth"']
|
118
|
+
@auth.valid_for?(@chal).should be_true
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should not be valid if the scheme is not "Basic"' do
|
122
|
+
@header['WWW-Authenticate'] = ["Digest"]
|
123
|
+
@auth.valid_for?(@chal).should be_false
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should not be valid if the realm does not match' do
|
127
|
+
@header['WWW-Authenticate'] = ['Basic realm="not test auth"']
|
128
|
+
@auth.valid_for?(@chal).should be_false
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should not be valid if the header is unreadable' do
|
132
|
+
@header['WWW-Authenticate'] = nil
|
133
|
+
@auth.valid_for?(@chal).should be_false
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should set the valid domain from the host part of the challenge uri' do
|
137
|
+
@auth.update_credentials(@chal)
|
138
|
+
@auth.instance_variable_get("@domain").should == 'example.com'
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
describe 'updating a request with credentials' do
|
144
|
+
before do
|
145
|
+
@auth.instance_variable_set("@domain", 'example.com')
|
146
|
+
@header = {}
|
147
|
+
@req = mock('request', :uri => 'http://example.com/bar/foo', :header => @header)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should be able to handle a request for the matching domain' do
|
151
|
+
@auth.can_handle?(@req).should be_true
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should add credentials to a request' do
|
155
|
+
@header.should_receive(:[]=).with('Authorization', 'Basic YWRtaW46c2VjcmV0')
|
156
|
+
@auth.add_credentials_to(@req)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should build the credentials string for the header' do
|
160
|
+
@auth.credentials.should == 'Basic YWRtaW46c2VjcmV0'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
describe Resourceful::DigestAuthenticator do
|
167
|
+
|
168
|
+
before do
|
169
|
+
@auth = Resourceful::DigestAuthenticator.new('Test Auth', 'admin', 'secret')
|
170
|
+
end
|
171
|
+
|
172
|
+
{:realm => 'Test Auth', :username => 'admin', :password => 'secret'}.each do |meth,val|
|
173
|
+
it "should initialize with a #{meth}" do
|
174
|
+
@auth.instance_variable_get("@#{meth}").should == val
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "Updating from a challenge response" do
|
179
|
+
before do
|
180
|
+
@header = {'WWW-Authenticate' => ['Digest realm="Test Auth"']}
|
181
|
+
@chal = mock('response', :header => @header, :uri => 'http://example.com/foo/bar')
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should be valid for a challenge response with scheme "Digest" and the same realm' do
|
185
|
+
@auth.valid_for?(@chal).should be_true
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should not be valid if the scheme is not "Digest"' do
|
189
|
+
@header['WWW-Authenticate'] = ["Basic"]
|
190
|
+
@auth.valid_for?(@chal).should be_false
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should not be valid if the realm does not match' do
|
194
|
+
@header['WWW-Authenticate'] = ['Digest realm="not test auth"']
|
195
|
+
@auth.valid_for?(@chal).should be_false
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should not be valid if the header is unreadable' do
|
199
|
+
@header['WWW-Authenticate'] = nil
|
200
|
+
@auth.valid_for?(@chal).should be_false
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname(__FILE__).dirname + '../spec_helper'
|
3
|
+
|
4
|
+
require 'resourceful/cache_manager'
|
5
|
+
|
6
|
+
describe Resourceful::CacheManager do
|
7
|
+
before do
|
8
|
+
@cm = Resourceful::InMemoryCacheManager.new #cheat, because I cant new a real one.
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should not be initializable' do
|
12
|
+
lambda { Resourceful::CacheManager.new }.should raise_error
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should have a lookup method' do
|
16
|
+
@cm.should respond_to(:lookup)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should have a store method' do
|
20
|
+
@cm.should respond_to(:store)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#select_request_headers' do
|
24
|
+
before do
|
25
|
+
@req_header = mock('header', :[] => nil)
|
26
|
+
@request = mock('request', :header => @req_header)
|
27
|
+
|
28
|
+
@resp_header = mock('header', :[] => nil)
|
29
|
+
@response = mock('response', :header => @resp_header)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should select the request headers from the Vary header' do
|
33
|
+
@resp_header.should_receive(:[]).with('Vary')
|
34
|
+
@cm.select_request_headers(@request, @response)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should pull the values from the request that match keys in the vary header' do
|
38
|
+
@resp_header.should_receive(:[]).with('Vary').twice.and_return(['foo', 'bar'])
|
39
|
+
@req_header.should_receive(:[]).with('foo').and_return('oof')
|
40
|
+
@req_header.should_receive(:[]).with('bar').and_return('rab')
|
41
|
+
|
42
|
+
header = @cm.select_request_headers(@request, @response)
|
43
|
+
header['foo'].should == 'oof'
|
44
|
+
header['bar'].should == 'rab'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should return a new Header object' do
|
48
|
+
@cm.select_request_headers(@request, @response).should be_kind_of(Resourceful::Header)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe Resourceful::NullCacheManager do
|
55
|
+
before do
|
56
|
+
@ncm = Resourceful::NullCacheManager.new
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should not find anything' do
|
60
|
+
@ncm.lookup(:stuff).should be_nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should not store anything' do
|
64
|
+
@ncm.should respond_to(:store)
|
65
|
+
|
66
|
+
lambda { @ncm.store(:foo, :bar) }.should_not raise_error
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
describe Resourceful::InMemoryCacheManager do
|
73
|
+
before do
|
74
|
+
@request = mock('request', :resource => mock('resource', :uri => 'uri'),
|
75
|
+
:request_time => Time.utc(2008,5,22,15,00))
|
76
|
+
@response = mock('response', :header => {})
|
77
|
+
|
78
|
+
@entry = mock('cache entry', :response => @response, :valid_for? => true)
|
79
|
+
Resourceful::InMemoryCacheManager::CacheEntry.stub!(:new).and_return(@entry)
|
80
|
+
|
81
|
+
@imcm = Resourceful::InMemoryCacheManager.new
|
82
|
+
end
|
83
|
+
|
84
|
+
describe 'finding' do
|
85
|
+
before do
|
86
|
+
@response.stub!(:authoritative=)
|
87
|
+
@imcm.instance_variable_set("@collection", {'uri' => {@request => @entry}})
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should lookup the response by request' do
|
91
|
+
@imcm.lookup(@request).should == @response
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should set the response to non-authoritative' do
|
95
|
+
@response.should_receive(:authoritative=).with(false)
|
96
|
+
@imcm.lookup(@request)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'saving' do
|
101
|
+
before do
|
102
|
+
@response.stub!(:cachable?).and_return(true)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should make a new cache entry' do
|
106
|
+
Resourceful::InMemoryCacheManager::CacheEntry.should_receive(:new).with(
|
107
|
+
Time.utc(2008,5,22,15,00),
|
108
|
+
{},
|
109
|
+
@response
|
110
|
+
)
|
111
|
+
|
112
|
+
@imcm.store(@request, @response)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should store the response entity by request' do
|
116
|
+
@imcm.store(@request, @response)
|
117
|
+
col = @imcm.instance_variable_get("@collection")
|
118
|
+
col['uri'][@request].response.should == @response
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should check if the response is cachable' do
|
122
|
+
@response.should_receive(:cachable?).and_return(true)
|
123
|
+
@imcm.store(@request, @response)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should not store an entry if the response is not cachable' do
|
127
|
+
@response.should_receive(:cachable?).and_return(false)
|
128
|
+
@imcm.store(@request, @response)
|
129
|
+
col = @imcm.instance_variable_get("@collection")
|
130
|
+
col['uri'][@request].should be_nil
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
describe Resourceful::InMemoryCacheManager::CacheEntryCollection do
|
137
|
+
before do
|
138
|
+
@entry_valid = mock('entry', :valid_for? => true)
|
139
|
+
@entry_invalid = mock('entry', :valid_for? => false)
|
140
|
+
|
141
|
+
@request = mock('request')
|
142
|
+
|
143
|
+
@collection = Resourceful::InMemoryCacheManager::CacheEntryCollection.new
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should find the right entry for a request' do
|
147
|
+
@collection.instance_variable_set('@entries', [@entry_valid, @entry_invalid])
|
148
|
+
@entry_valid.should_receive(:valid_for?).with(@request).and_return(true)
|
149
|
+
@collection[@request].should == @entry_valid
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should be nil if no matching entry was found' do
|
153
|
+
@collection.instance_variable_set('@entries', [@entry_invalid])
|
154
|
+
@entry_invalid.should_receive(:valid_for?).with(@request).and_return(false)
|
155
|
+
@collection[@request].should == nil
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should store an entry' do
|
159
|
+
@collection[@request] = @entry_valid
|
160
|
+
@collection.instance_variable_get("@entries").should include(@entry_valid)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should replace an existing entry if the existing entry matches the request' do
|
164
|
+
@new_entry = mock('entry', :valid_for? => true)
|
165
|
+
|
166
|
+
@collection[@request] = @entry_valid
|
167
|
+
@collection[@request] = @new_entry
|
168
|
+
|
169
|
+
@collection.instance_variable_get("@entries").should include(@new_entry)
|
170
|
+
@collection.instance_variable_get("@entries").should_not include(@entry_valid)
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
describe Resourceful::InMemoryCacheManager::CacheEntry do
|
176
|
+
before do
|
177
|
+
@entry = Resourceful::InMemoryCacheManager::CacheEntry.new(
|
178
|
+
Time.utc(2008,5,16,0,0,0), {'Content-Type' => 'text/plain'}, mock('response')
|
179
|
+
)
|
180
|
+
|
181
|
+
@request = mock('request')
|
182
|
+
end
|
183
|
+
|
184
|
+
[:request_time, :request_vary_headers, :response, :valid_for?].each do |method|
|
185
|
+
it "should respond to ##{method}" do
|
186
|
+
@entry.should respond_to(method)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should be valid for a request if all the vary headers match' do
|
191
|
+
@request.stub!(:header).and_return({'Content-Type' => 'text/plain'})
|
192
|
+
@entry.valid_for?(@request).should be_true
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should not be valid for a request if not all the vary headers match' do
|
196
|
+
@request.stub!(:header).and_return({'Content-Type' => 'text/html'})
|
197
|
+
@entry.valid_for?(@request).should be_false
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname(__FILE__).dirname + '../spec_helper'
|
3
|
+
|
4
|
+
require 'resourceful/header'
|
5
|
+
|
6
|
+
describe Resourceful::Header do
|
7
|
+
|
8
|
+
it "should capitalize on all accesses" do
|
9
|
+
h = Resourceful::Header.new("foo" => "bar")
|
10
|
+
h["foo"].should == "bar"
|
11
|
+
h["Foo"].should == "bar"
|
12
|
+
h["FOO"].should == "bar"
|
13
|
+
|
14
|
+
h.to_hash.should == {"Foo" => "bar"}
|
15
|
+
|
16
|
+
h["bar-zzle"] = "quux"
|
17
|
+
|
18
|
+
h.to_hash.should == {"Foo" => "bar", "Bar-Zzle" => "quux"}
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should capitalize correctly" do
|
22
|
+
h = Resourceful::Header.new
|
23
|
+
|
24
|
+
h.capitalize("foo").should == "Foo"
|
25
|
+
h.capitalize("foo-bar").should == "Foo-Bar"
|
26
|
+
h.capitalize("foo_bar").should == "Foo_Bar"
|
27
|
+
h.capitalize("foo bar").should == "Foo Bar"
|
28
|
+
h.capitalize("foo-bar-quux").should == "Foo-Bar-Quux"
|
29
|
+
h.capitalize("foo-bar-2quux").should == "Foo-Bar-2quux"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be converted to real Hash" do
|
33
|
+
h = Resourceful::Header.new("foo" => "bar")
|
34
|
+
h.to_hash.should be_instance_of(Hash)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname(__FILE__).dirname + '../spec_helper'
|
3
|
+
|
4
|
+
require 'resourceful/http_accessor'
|
5
|
+
|
6
|
+
describe Resourceful::HttpAccessor, 'init' do
|
7
|
+
|
8
|
+
it 'should be instantiatable' do
|
9
|
+
Resourceful::HttpAccessor.new().should be_instance_of(Resourceful::HttpAccessor)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should accept logger to new' do
|
13
|
+
ha = Resourceful::HttpAccessor.new(:logger => (l = stub('logger')))
|
14
|
+
|
15
|
+
ha.logger.should == l
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should provide logger object even when no logger is specified' do
|
19
|
+
ha = Resourceful::HttpAccessor.new()
|
20
|
+
|
21
|
+
ha.logger.should be_instance_of(Resourceful::HttpAccessor::BitBucketLogger)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should raise arg error if unrecognized options are passed' do
|
25
|
+
lambda {
|
26
|
+
ha = Resourceful::HttpAccessor.new(:foo => 'foo', :bar => 'bar')
|
27
|
+
}.should raise_error(ArgumentError, /Unrecognized options: (foo, bar)|(bar, foo)/)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should allow an additional user agent token to be passed at init' do
|
31
|
+
Resourceful::HttpAccessor.new(:user_agent => "Super/3000").tap do |ha|
|
32
|
+
ha.user_agent_string.should match(%r{^Super/3000})
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should allow multiple additional user agent tokens to be passed at init' do
|
37
|
+
Resourceful::HttpAccessor.new(:user_agent => ["Super/3000", "Duper/2.1"]).tap do |ha|
|
38
|
+
ha.user_agent_string.should match(%r{^Super/3000 Duper/2\.1 })
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
describe Resourceful::HttpAccessor do
|
45
|
+
before do
|
46
|
+
@logger = stub('logger')
|
47
|
+
@accessor = Resourceful::HttpAccessor.new(:logger => @logger)
|
48
|
+
@auth_manager = mock('authentication_manager')
|
49
|
+
Resourceful::AuthenticationManager.stub!(:new).and_return(@auth_manager)
|
50
|
+
|
51
|
+
@resource = mock('resource')
|
52
|
+
Resourceful::Resource.stub!(:new).and_return(@resource)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should have user agent string w/ just resourceful token by default' do
|
56
|
+
@accessor.user_agent_string.should == "Resourceful/#{RESOURCEFUL_VERSION}(Ruby/#{RUBY_VERSION})"
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should add additional user agent tokens to beginning of user agent string' do
|
60
|
+
@accessor.user_agent_tokens << 'FooBar/3000(special-version)'
|
61
|
+
|
62
|
+
@accessor.user_agent_string.should match(%r{^FooBar\/3000\(special-version\) Resourceful/})
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should allow a logger to be specified' do
|
66
|
+
l = stub('logger')
|
67
|
+
|
68
|
+
@accessor.logger = l
|
69
|
+
@accessor.logger.should == l
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should allow a logger to be removed' do
|
73
|
+
l = stub('logger')
|
74
|
+
|
75
|
+
@accessor.logger = l
|
76
|
+
@accessor.logger = nil
|
77
|
+
@accessor.logger.should be_nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should be able to return a particular resource (#[])' do
|
81
|
+
@accessor['http://www.example/'].should == @resource
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should create resource if it does not already exist (#[])' do
|
85
|
+
Resourceful::Resource.should_receive(:new).and_return(stub('resource'))
|
86
|
+
@accessor['http://www.example/previously-unused-uri']
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should pass uri to resource upon creation (#[])' do
|
90
|
+
Resourceful::Resource.should_receive(:new).with(anything, 'http://www.example/previously-unused-uri').
|
91
|
+
and_return(stub('resource'))
|
92
|
+
@accessor['http://www.example/previously-unused-uri']
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should pass owning accessor to resource upon creation (#[])' do
|
96
|
+
Resourceful::Resource.should_receive(:new).with(@accessor, anything).and_return(stub('resource'))
|
97
|
+
@accessor['http://www.example/previously-unused-uri']
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should be able to return a particular resource (#resource)' do
|
101
|
+
@accessor.resource('http://www.example/').should == @resource
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should create resource if it does not already exist (#resource)' do
|
105
|
+
Resourceful::Resource.should_receive(:new).and_return(stub('resource'))
|
106
|
+
@accessor.resource('http://www.example/previously-unused-uri')
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should pass owning accessor to resource upon creation (#[])' do
|
110
|
+
Resourceful::Resource.should_receive(:new).with(@accessor, anything).and_return(stub('resource'))
|
111
|
+
@accessor.resource('http://www.example/previously-unused-uri')
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should pass uri to resource upon creation (#resource)' do
|
115
|
+
Resourceful::Resource.should_receive(:new).with(anything, 'http://www.example/previously-unused-uri').
|
116
|
+
and_return(stub('resource'))
|
117
|
+
@accessor.resource('http://www.example/previously-unused-uri')
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|