harpy 0.1.0

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.
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+
3
+ describe Harpy::EntryPoint do
4
+ let(:url) { "http://localhost" }
5
+ subject { Harpy::EntryPoint.new url}
6
+
7
+ it "should store url" do
8
+ subject.url.should == url
9
+ end
10
+
11
+ describe "#resource_url(resource_type)" do
12
+ let(:company_url) { "#{url}/company"}
13
+ let(:json_response) { %Q|{"link": [{"rel": "company", "href": "#{company_url}"}]}| }
14
+ let(:success_response) { Typhoeus::Response.new :code => 200, :body => json_response }
15
+ let(:error_response) { Typhoeus::Response.new :code => 500 }
16
+ it "gets entry point from url using client" do
17
+ Harpy.client.should_receive(:get).with(url).and_return success_response
18
+ subject.resource_url "user"
19
+ end
20
+ it "return nil if no link for resource_type" do
21
+ Harpy.client.should_receive(:get).with(url).and_return success_response
22
+ subject.resource_url("user").should be_nil
23
+ end
24
+ it "return url for existing resource_type" do
25
+ Harpy.client.should_receive(:get).with(url).and_return success_response
26
+ subject.resource_url("company_url").should be_nil
27
+ end
28
+ it "delegates response code != 200 to client" do
29
+ Harpy.client.should_receive(:get).with(url).and_return error_response
30
+ Harpy.client.should_receive(:invalid_code).with error_response
31
+ subject.resource_url("company_url")
32
+ end
33
+ end
34
+
35
+ describe "#urn(urn)" do
36
+ let(:urn) { "urn:harpy:company:1" }
37
+ let(:company_url) { "#{url}/company/1"}
38
+ let(:success_response) { Typhoeus::Response.new :code => 301, :headers => "Location: #{company_url}" }
39
+ let(:error_response) { Typhoeus::Response.new :code => 500 }
40
+ let(:not_found_response) { Typhoeus::Response.new :code => 404 }
41
+ it "query remote for this urn using client" do
42
+ Harpy.client.should_receive(:get).with("#{url}/#{urn}").and_return success_response
43
+ subject.urn(urn).should == company_url
44
+ end
45
+ it "return nil if not found" do
46
+ Harpy.client.should_receive(:get).with("#{url}/#{urn}").and_return not_found_response
47
+ subject.urn(urn).should be_nil
48
+ end
49
+ it "delegates response code != 301 or 404 to client" do
50
+ Harpy.client.should_receive(:get).with("#{url}/#{urn}").and_return error_response
51
+ Harpy.client.should_receive(:invalid_code).with error_response
52
+ subject.urn(urn)
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,516 @@
1
+ require "spec_helper"
2
+
3
+ describe Harpy::Resource do
4
+ describe ".from_url(hash)" do
5
+ let(:company_url) { "http://localhost/company/1" }
6
+ let(:json_response) { %Q|{"name": "Harpy ltd", "link": [{"rel": "self", "href": "#{company_url}"}]}| }
7
+ let(:success_response) { Typhoeus::Response.new :code => 200, :body => json_response}
8
+ it "queries multiple resources in parallel and return instances" do
9
+ Typhoeus::Hydra.hydra.stub(:get, company_url).and_return success_response
10
+ responses = Harpy::Resource.from_url({ Harpy::Spec::Company => [company_url] })
11
+ responses.should have(1).keys
12
+ responses[Harpy::Spec::Company].should have(1).item
13
+ responses[Harpy::Spec::Company].first.name.should == "Harpy ltd"
14
+ end
15
+ end
16
+ end
17
+
18
+ module Harpy
19
+ module Spec
20
+ class Company
21
+ include Harpy::Resource
22
+ end
23
+ class User
24
+ include Harpy::Resource
25
+ validates_presence_of :firstname
26
+ before_validation :check_lastname
27
+ before_save :callback_before_save
28
+ before_create :callback_before_create
29
+ before_update :callback_before_update
30
+ attr_reader :callbacks
31
+ def initialize(*args)
32
+ @callbacks = []
33
+ super
34
+ end
35
+ def check_lastname
36
+ !!lastname
37
+ end
38
+ def callback_before_save
39
+ @callbacks << :save
40
+ end
41
+ def callback_before_create
42
+ @callbacks << :create
43
+ end
44
+ def callback_before_update
45
+ @callbacks << :update
46
+ end
47
+ end
48
+ end
49
+ end
50
+ describe "class including Harpy::Resource" do
51
+ subject{ Harpy::Spec::Company.new }
52
+ after{ Harpy.reset }
53
+ describe ".from_url(url)" do
54
+ context "called with only one url" do
55
+ let(:url){ "http://localhost/company/1" }
56
+ it "is a properly filled-in instance of Harpy::Spec::Company on success" do
57
+ response = Typhoeus::Response.new :code => 200, :body => <<-eos
58
+ {
59
+ "name": "Harpy Ltd",
60
+ "link": [
61
+ {"rel": "self", "href": "#{url}"}
62
+ ]
63
+ }
64
+ eos
65
+ Harpy.client.should_receive(:get).with(url).and_return response
66
+ result = Harpy::Spec::Company.from_url url
67
+ result.should be_kind_of Harpy::Spec::Company
68
+ result.name.should == "Harpy Ltd"
69
+ result.link("self").should == url
70
+ end
71
+ it "is nil when not found" do
72
+ response = Typhoeus::Response.new :code => 404
73
+ Harpy.client.should_receive(:get).with(url).and_return response
74
+ Harpy::Spec::Company.from_url(url).should be_nil
75
+ end
76
+ it "delegates response code != 200 or 404 to client" do
77
+ response = Typhoeus::Response.new :code => 500
78
+ Harpy.client.should_receive(:get).with(url).and_return response
79
+ Harpy.client.should_receive(:invalid_code).with response
80
+ Harpy::Spec::Company.from_url(url)
81
+ end
82
+ end
83
+ end
84
+ describe ".from_id(id)" do
85
+ context "when entry point is configured" do
86
+ it "raises Harpy::EntryPointRequired" do
87
+ lambda{
88
+ Harpy::Spec::Company.from_id(1)
89
+ }.should raise_error Harpy::EntryPointRequired
90
+ end
91
+ end
92
+ context "when entry point is set but urn has not been overriden" do
93
+ it "raises NotImplementedError" do
94
+ Harpy.entry_point_url = "http://localhost"
95
+ lambda{
96
+ Harpy::Spec::Company.from_id(1)
97
+ }.should raise_error NotImplementedError
98
+ end
99
+ end
100
+ context "when entry point is set and urn has been overriden" do
101
+ let(:urn) { "urn:harpy:company:1" }
102
+ let(:url) { "http://localhost/company/1" }
103
+ it "asks Harpy.entry_point to convert urn to url then call .from_url" do
104
+ # 1 -> urn:harpy:company:1
105
+ Harpy::Spec::Company.should_receive(:urn).with(1).and_return urn
106
+
107
+ # urn:harpy:company:1 -> http://localhost/company/1
108
+ Harpy.entry_point = mock
109
+ Harpy.entry_point.should_receive(:urn).with(urn).and_return url
110
+
111
+ # http://localhost/company/1 -> Harpy::Spec::Company instance
112
+ Harpy::Spec::Company.should_receive(:from_url).with(url).and_return(expected = mock)
113
+ Harpy::Spec::Company.from_id(1).should be expected
114
+ end
115
+ it "is nil if urn is not found" do
116
+ # 1 -> urn:harpy:company:1
117
+ Harpy::Spec::Company.should_receive(:urn).with(1).and_return urn
118
+
119
+ # urn:harpy:company:1 -> nil
120
+ Harpy.entry_point = mock
121
+ Harpy.entry_point.should_receive(:urn).with(urn)
122
+
123
+ Harpy::Spec::Company.from_id(1).should be_nil
124
+ end
125
+ end
126
+ end
127
+ describe ".urn(id)" do
128
+ it "raises NotImplementedError" do
129
+ lambda{
130
+ Harpy::Spec::Company.urn(1)
131
+ }.should raise_error NotImplementedError
132
+ end
133
+ end
134
+ describe ".resource_name" do
135
+ it "defaults to underscored class name" do
136
+ Harpy::Spec::Company.resource_name.should == "harpy/spec/company"
137
+ end
138
+ end
139
+ describe ".search(conditions)" do
140
+ let(:url){ "http://localhost/company" }
141
+ before do
142
+ Harpy.entry_point = mock
143
+ Harpy.entry_point.should_receive(:resource_url).with("harpy/spec/company").and_return url
144
+ end
145
+ it "return properly filled instances on 200" do
146
+ response = Typhoeus::Response.new :code => 200, :body => <<-eos
147
+ {
148
+ "harpy/spec/company": [
149
+ {
150
+ "firstname": "Anthony",
151
+ "urn": "urn:harpy:company:1",
152
+ "link": [
153
+ {"rel": "self", "href": "#{url}/1"}
154
+ ]
155
+ }
156
+ ],
157
+ "link": [
158
+ {"rel": "self", "href": "#{url}"}
159
+ ]
160
+ }
161
+ eos
162
+ Harpy.client.should_receive(:get).with(url, :params => {"firstname" => "Anthony"}).and_return response
163
+ companies = Harpy::Spec::Company.search "firstname" => "Anthony"
164
+ companies.should have(1).item
165
+ companies.first.should be_kind_of Harpy::Spec::Company
166
+ companies.first.firstname.should == "Anthony"
167
+ companies.first.id.should == "1"
168
+ end
169
+ it "delegates other response codes to client" do
170
+ response = Typhoeus::Response.new :code => 500
171
+ Harpy.client.should_receive(:get).with(url, :params => {}).and_return response
172
+ Harpy.client.should_receive(:invalid_code).with response
173
+ Harpy::Spec::Company.search
174
+ end
175
+ end
176
+ describe ".with_url(url)" do
177
+ let(:url){ "http://localhost/user/1/company" }
178
+ it "overrides url used for searches" do
179
+ response = Typhoeus::Response.new :code => 500
180
+ Harpy.client.should_receive(:get).with(url, :params => {}).and_return response
181
+ Harpy.client.should_receive(:invalid_code).with response
182
+ Harpy::Spec::Company.with_url(url) do
183
+ Harpy::Spec::Company.search
184
+ end
185
+ end
186
+ it "can be nested" do
187
+ url2 = "http://localhost/user/2/company"
188
+ response = Typhoeus::Response.new :code => 500
189
+ Harpy.client.should_receive(:get).ordered.with(url2, :params => {}).and_return response
190
+ Harpy.client.should_receive(:get).ordered.with(url, :params => {}).and_return response
191
+ Harpy.client.should_receive(:invalid_code).twice.with response
192
+ Harpy::Spec::Company.with_url(url) do
193
+ Harpy::Spec::Company.with_url(url2) do
194
+ Harpy::Spec::Company.search
195
+ end
196
+ Harpy::Spec::Company.search
197
+ end
198
+ end
199
+ end
200
+ describe "mass assignment" do
201
+ it "sets any attribute on initialization" do
202
+ company = Harpy::Spec::Company.new "name" => "Harpy Ltd"
203
+ company.name.should == "Harpy Ltd"
204
+ end
205
+ it "initialization works with string keys only" do
206
+ company = Harpy::Spec::Company.new :name => "Harpy Ltd"
207
+ company.name.should be_nil
208
+ end
209
+ it "#attributes=(attrs) merges new attributes with previous ones" do
210
+ company = Harpy::Spec::Company.new "name" => "Harpy Ltd", "deleted" => false
211
+ company.attributes = {"name" => "Harpy Inc", "custom" => true}
212
+ company.name.should eql "Harpy Inc"
213
+ company.deleted.should be_false
214
+ company.custom.should be_true
215
+ end
216
+ it "#attributes=(attrs) works with string keys only" do
217
+ company = Harpy::Spec::Company.new "name" => "Harpy Ltd"
218
+ company.attributes = {:name => "Harpy Inc"}
219
+ company.name.should eql "Harpy Ltd"
220
+ end
221
+ it "doesn't define writers for each attribute" do
222
+ company = Harpy::Spec::Company.new "name" => "Harpy Ltd"
223
+ company.should_not respond_to(:name=)
224
+ end
225
+ it "allows accessing undefined attributes when not persisted" do
226
+ subject.name.should be_nil
227
+ end
228
+ it "doesn't allows accessing undefined attributes when not persisted" do
229
+ subject.should_receive(:persisted?).and_return true
230
+ lambda{ subject.name }.should raise_error NoMethodError
231
+ end
232
+ end
233
+ describe "advanced attribute readers" do
234
+ let(:url){ "http://localhost/company/1" }
235
+ subject{ Harpy::Spec::Company.new "link" => [{"rel" => "self", "href" => url}] }
236
+ describe "#link(rel)" do
237
+ it "searches link with matching rel and return href" do
238
+ subject.link("self").should == url
239
+ end
240
+ it "works with symbols too" do
241
+ subject.link(:self).should == url
242
+ end
243
+ it "is nil if no matching link can be found" do
244
+ subject.link("user").should be_nil
245
+ end
246
+ end
247
+ describe "#url" do
248
+ it "searches url to self inside links" do
249
+ subject.should_receive(:link).with("self").and_return (expected = mock)
250
+ subject.url.should be expected
251
+ end
252
+ it "is nil when no link to self can be found" do
253
+ subject.should_receive(:link).with "self"
254
+ subject.url.should be_nil
255
+ end
256
+ end
257
+ describe "#url_collection" do
258
+ it "defaults to entry_point link which rel matches resource name" do
259
+ Harpy.entry_point = mock
260
+ Harpy.entry_point.should_receive(:resource_url).with("harpy/spec/company").and_return (expected = mock)
261
+ subject.url_collection.should be expected
262
+ end
263
+ end
264
+ describe "#id" do
265
+ it "extracts last part from urn" do
266
+ company = Harpy::Spec::Company.new "urn" => "urn:harpy:company:1"
267
+ company.id.should == "1"
268
+ end
269
+ it "works with alphanumeric ids too" do
270
+ company = Harpy::Spec::Company.new "urn" => "urn:harpy:company:e{39,^"
271
+ company.id.should == "e{39,^"
272
+ end
273
+ it "works with urns having more than 4 parts" do
274
+ company = Harpy::Spec::Company.new "urn" => "urn:harpy:api:company:1"
275
+ company.id.should == "1"
276
+ end
277
+ it "is nil without urn" do
278
+ subject.id.should be_nil
279
+ end
280
+ it "is nil if urn is an empty string" do
281
+ company = Harpy::Spec::Company.new "urn" => ""
282
+ company.id.should be_nil
283
+ end
284
+ it "never uses manually assigned id attribute" do
285
+ company = Harpy::Spec::Company.new "id" => "1"
286
+ company.id.should be_nil
287
+ end
288
+ end
289
+ describe "#persisted?" do
290
+ it "defaults to false when no urn is defined" do
291
+ company = Harpy::Spec::Company.new
292
+ company.persisted?.should be_false
293
+ end
294
+ it "is true when an urn is present" do
295
+ company = Harpy::Spec::Company.new "urn" => "urn:harpy:company:1"
296
+ company.persisted?.should be_true
297
+ end
298
+ it "is false when urn is an empty string" do
299
+ company = Harpy::Spec::Company.new "urn" => ""
300
+ company.persisted?.should be_false
301
+ end
302
+ end
303
+ describe "#inspect" do
304
+ subject { Harpy::Spec::Company.new "firstname" => "Anthony" }
305
+ it "shows class name, attributes, errors and persisted state" do
306
+ if RUBY_VERSION.to_f < 1.9
307
+ subject.inspect.should == '<Harpy::Spec::Company @attrs:{"firstname"=>"Anthony"} @errors:#<OrderedHash {}> persisted:false>'
308
+ else
309
+ subject.inspect.should == '<Harpy::Spec::Company @attrs:{"firstname"=>"Anthony"} @errors:{} persisted:false>'
310
+ end
311
+ end
312
+ end
313
+ describe "#has_key?(key)" do
314
+ it "is true when attribute is present" do
315
+ subject.has_key?("link").should be_true
316
+ end
317
+ it "does accept symbols too" do
318
+ subject.has_key?(:link).should be_true
319
+ end
320
+ it "is true when attribute is an empty string" do
321
+ company = Harpy::Spec::Company.new "urn" => ""
322
+ company.has_key?("urn").should be_true
323
+ end
324
+ it "is false when attribute is not defined" do
325
+ subject.has_key?("custom").should be_false
326
+ end
327
+ it "is false when key matches an existing method but not an attribute" do
328
+ subject.has_key?(:url).should be_false
329
+ end
330
+ it "does not raise error when checking for an undefined attribute even when persisted" do
331
+ subject.stub(:persisted?).and_return true
332
+ subject.has_key?("custom").should be_false
333
+ end
334
+ end
335
+ end
336
+ describe "#valid?" do
337
+ it "has ActiveModel validations" do
338
+ user = Harpy::Spec::User.new "lastname" => "Stark"
339
+ user.should_not be_valid
340
+ user.should have(1).error
341
+ user.errors[:firstname].should =~ ["can't be blank"]
342
+ end
343
+ it "calls before_validation which prevents validation on false" do
344
+ user = Harpy::Spec::User.new
345
+ user.should_not be_valid
346
+ user.should have(:no).error
347
+ end
348
+ end
349
+ describe "#as_json" do
350
+ let(:url) { "http://localhost/user/1" }
351
+ subject do
352
+ Harpy::Spec::User.new({
353
+ "urn" => "urn:harpy:user:1",
354
+ "company_name" => "Stark Enterprises",
355
+ "link" => [{"rel" => "self", "href" => url}],
356
+ })
357
+ end
358
+
359
+ it "exclude link and urn from attributes" do
360
+ subject.as_json.should == {"company_name" => "Stark Enterprises"}
361
+ end
362
+ it "does not remove link and urn from object attributes" do
363
+ subject.as_json
364
+ subject.urn.should == "urn:harpy:user:1"
365
+ subject.url.should == url
366
+ end
367
+ end
368
+ describe "#save" do
369
+ subject{ Harpy::Spec::User.new "company_name" => "Stark Enterprises" }
370
+ it "is false and does not call before_save callback if not valid" do
371
+ subject.should_receive :valid?
372
+ subject.save.should be_false
373
+ subject.callbacks.should =~ []
374
+ end
375
+ context "on create (valid, not persisted)" do
376
+ let(:url) { "http://localhost/user" }
377
+ let(:body) { '{"company_name":"Stark Enterprises"}' }
378
+ before do
379
+ subject.should_receive(:valid?).and_return true
380
+ subject.should_receive(:url_collection).and_return url
381
+ end
382
+ [200, 201, 302].each do |response_code|
383
+ it "is true and merges response attributes on #{response_code}" do
384
+ response = Typhoeus::Response.new :code => response_code, :body => <<-eos
385
+ {
386
+ "firstname": "Anthony",
387
+ "urn": "urn:harpy:user:1",
388
+ "link": [
389
+ {"rel": "self", "href": "#{url}/1"}
390
+ ]
391
+ }
392
+ eos
393
+ Harpy.client.should_receive(:post).with(url, :body => body).and_return response
394
+ subject.save.should be_true
395
+ subject.callbacks.should =~ [:save, :create]
396
+ subject.firstname.should == "Anthony"
397
+ subject.company_name.should == "Stark Enterprises"
398
+ subject.urn.should == "urn:harpy:user:1"
399
+ end
400
+ end
401
+ it "raises Harpy::InvalidResponseCode on 204" do
402
+ response = Typhoeus::Response.new :code => 204
403
+ Harpy.client.should_receive(:post).with(url, :body => body).and_return response
404
+ lambda { subject.save }.should raise_error Harpy::InvalidResponseCode, "204"
405
+ subject.callbacks.should =~ [:save, :create]
406
+ end
407
+ it "raises Harpy::Unauthorized on 401" do
408
+ response = Typhoeus::Response.new :code => 401
409
+ Harpy.client.should_receive(:post).with(url, :body => body).and_return response
410
+ lambda { subject.save }.should raise_error Harpy::Unauthorized, "Server returned a 401 response code"
411
+ subject.callbacks.should =~ [:save, :create]
412
+ end
413
+ it "is false and fills in errors on 422" do
414
+ response = Typhoeus::Response.new :code => 422, :body => <<-eos
415
+ {
416
+ "firstname": "Anthony",
417
+ "errors": {
418
+ "lastname": ["can't be blank", "must be unique"]
419
+ }
420
+ }
421
+ eos
422
+ Harpy.client.should_receive(:post).with(url, :body => body).and_return response
423
+ subject.save.should be_false
424
+ subject.callbacks.should =~ [:save, :create]
425
+ subject.should have(1).error
426
+ subject.errors[:lastname].should =~ ["can't be blank", "must be unique"]
427
+ subject.firstname.should be_nil
428
+ subject.company_name.should == "Stark Enterprises"
429
+ end
430
+ it "delegates other response codes to client" do
431
+ response = Typhoeus::Response.new :code => 500
432
+ Harpy.client.should_receive(:post).with(url, :body => body).and_return response
433
+ Harpy.client.should_receive(:invalid_code).with(response)
434
+ subject.save
435
+ subject.callbacks.should =~ [:save, :create]
436
+ end
437
+ end
438
+ context "on update (valid, persisted but link to self is not present)" do
439
+ it "raises Harpy::UrlRequired" do
440
+ subject.should_receive(:valid?).and_return true
441
+ subject.should_receive(:persisted?).and_return true
442
+ lambda{ subject.save }.should raise_error Harpy::UrlRequired
443
+ subject.callbacks.should =~ [:save, :update]
444
+ end
445
+ end
446
+ context "on update (valid, persisted and link to self is present)" do
447
+ let(:url) { "http://localhost/user/1" }
448
+ let(:body) { '{"company_name":"Stark Enterprises"}' }
449
+ subject do
450
+ Harpy::Spec::User.new({
451
+ "urn" => "urn:harpy:user:1",
452
+ "company_name" => "Stark Enterprises",
453
+ "link" => [{"rel" => "self", "href" => url}],
454
+ })
455
+ end
456
+ before do
457
+ subject.should_receive(:valid?).and_return true
458
+ end
459
+ [200, 201, 302].each do |response_code|
460
+ it "is true and merges response attributes on #{response_code}" do
461
+ response = Typhoeus::Response.new :code => response_code, :body => <<-eos
462
+ {
463
+ "firstname": "Anthony",
464
+ "urn": "urn:harpy:user:1",
465
+ "link": [
466
+ {"rel": "self", "href": "#{url}/1"}
467
+ ]
468
+ }
469
+ eos
470
+ Harpy.client.should_receive(:put).with(url, :body => body).and_return response
471
+ subject.save.should be_true
472
+ subject.callbacks.should =~ [:save, :update]
473
+ subject.firstname.should == "Anthony"
474
+ subject.company_name.should == "Stark Enterprises"
475
+ end
476
+ end
477
+ it "is true but doesn't touch attributes on 204" do
478
+ response = Typhoeus::Response.new :code => 204
479
+ Harpy.client.should_receive(:put).with(url, :body => body).and_return response
480
+ subject.save.should be_true
481
+ subject.callbacks.should =~ [:save, :update]
482
+ subject.company_name.should == "Stark Enterprises"
483
+ end
484
+ it "raises Harpy::Unauthorized on 401" do
485
+ response = Typhoeus::Response.new :code => 401
486
+ Harpy.client.should_receive(:put).with(url, :body => body).and_return response
487
+ lambda { subject.save }.should raise_error Harpy::Unauthorized, "Server returned a 401 response code"
488
+ subject.callbacks.should =~ [:save, :update]
489
+ end
490
+ it "is false and fills in errors on 422" do
491
+ response = Typhoeus::Response.new :code => 422, :body => <<-eos
492
+ {
493
+ "firstname": "Anthony",
494
+ "errors": {
495
+ "lastname": ["can't be blank", "must be unique"]
496
+ }
497
+ }
498
+ eos
499
+ Harpy.client.should_receive(:put).with(url, :body => body).and_return response
500
+ subject.save.should be_false
501
+ subject.callbacks.should =~ [:save, :update]
502
+ subject.should have(1).error
503
+ subject.errors[:lastname].should =~ ["can't be blank", "must be unique"]
504
+ lambda { subject.firstname }.should raise_error NoMethodError
505
+ subject.company_name.should == "Stark Enterprises"
506
+ end
507
+ it "delegates other response codes to client" do
508
+ response = Typhoeus::Response.new :code => 500
509
+ Harpy.client.should_receive(:put).with(url, :body => body).and_return response
510
+ Harpy.client.should_receive(:invalid_code).with(response)
511
+ subject.save
512
+ subject.callbacks.should =~ [:save, :update]
513
+ end
514
+ end
515
+ end
516
+ end
@@ -0,0 +1,97 @@
1
+ require "spec_helper"
2
+
3
+ describe Harpy do
4
+ after{ Harpy.reset }
5
+
6
+ it "defaults to Harpy::Client" do
7
+ Harpy.client.should be_kind_of Harpy::Client
8
+ end
9
+
10
+ it "does allow using another client" do
11
+ custom_client = mock
12
+ Harpy.client = custom_client
13
+ Harpy.client.should be custom_client
14
+ end
15
+
16
+ it "has no default entry_point_url" do
17
+ Harpy.entry_point_url.should be_nil
18
+ end
19
+
20
+ it "does allow setting an entry_point_url" do
21
+ Harpy.entry_point_url = "http://localhost"
22
+ Harpy.entry_point_url.should == "http://localhost"
23
+ end
24
+
25
+ it "raises Harpy::EntryPointRequired when trying to access entry_point and none has been created yet" do
26
+ lambda{ Harpy.entry_point }.should raise_error Harpy::EntryPointRequired
27
+ end
28
+
29
+ it "returns a valid Harpy::EntryPoint object if entry_point_url has been set" do
30
+ Harpy.entry_point_url = "http://localhost"
31
+ Harpy.entry_point.should be_kind_of Harpy::EntryPoint
32
+ Harpy.entry_point.url.should == "http://localhost"
33
+ end
34
+
35
+ it "does allow setting entry_point manually" do
36
+ Harpy.entry_point = (entry_point = mock)
37
+ Harpy.entry_point.should be entry_point
38
+ entry_point.should_receive(:url).and_return "http://localhost"
39
+ Harpy.entry_point_url.should == "http://localhost"
40
+ end
41
+
42
+ it "Harpy.reset clears both client and entry_point" do
43
+ Harpy.entry_point_url = "http://localhost"
44
+ Harpy.client = (custom_client = mock)
45
+ Harpy.reset
46
+ Harpy.entry_point_url.should be_nil
47
+ Harpy.client.should_not be custom_client
48
+ end
49
+ end
50
+
51
+ describe Harpy::Exception do
52
+ it "is an ::Exception" do
53
+ Harpy::Exception.ancestors.should include ::Exception
54
+ end
55
+ end
56
+
57
+ describe Harpy::EntryPointRequired do
58
+ it "is an Harpy::Exception" do
59
+ Harpy::EntryPointRequired.ancestors.should include Harpy::Exception
60
+ end
61
+ end
62
+
63
+ describe Harpy::UrlRequired do
64
+ it "is an Harpy::Exception" do
65
+ Harpy::UrlRequired.ancestors.should include Harpy::Exception
66
+ end
67
+ end
68
+
69
+ describe Harpy::BodyToBig do
70
+ it "is an Harpy::Exception" do
71
+ Harpy::BodyToBig.ancestors.should include Harpy::Exception
72
+ end
73
+ end
74
+
75
+ describe Harpy::ClientTimeout do
76
+ it "is an Harpy::Exception" do
77
+ Harpy::ClientTimeout.ancestors.should include Harpy::Exception
78
+ end
79
+ end
80
+
81
+ describe Harpy::ClientError do
82
+ it "is an Harpy::Exception" do
83
+ Harpy::ClientError.ancestors.should include Harpy::Exception
84
+ end
85
+ end
86
+
87
+ describe Harpy::Unauthorized do
88
+ it "is an Harpy::Exception" do
89
+ Harpy::Unauthorized.ancestors.should include Harpy::Exception
90
+ end
91
+ end
92
+
93
+ describe Harpy::InvalidResponseCode do
94
+ it "is an Harpy::Exception" do
95
+ Harpy::InvalidResponseCode.ancestors.should include Harpy::Exception
96
+ end
97
+ end
@@ -0,0 +1,13 @@
1
+ require "harpy"
2
+ require "typhoeus"
3
+
4
+ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each{|f| require f}
5
+
6
+ # Do not allow external connections
7
+ Typhoeus::Hydra.allow_net_connect = false
8
+
9
+ RSpec.configure do |config|
10
+ config.after(:each) do
11
+ Typhoeus::Hydra.hydra.clear_stubs
12
+ end
13
+ end