resto 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/lib/blankslate.rb +110 -0
  2. data/lib/resto.rb +264 -0
  3. data/lib/resto/attributes.rb +56 -0
  4. data/lib/resto/extra/copy.rb +34 -0
  5. data/lib/resto/extra/delegation.rb +26 -0
  6. data/lib/resto/extra/hash_args.rb +56 -0
  7. data/lib/resto/format.rb +20 -0
  8. data/lib/resto/format/default.rb +11 -0
  9. data/lib/resto/format/json.rb +30 -0
  10. data/lib/resto/format/plain.rb +14 -0
  11. data/lib/resto/format/xml.rb +66 -0
  12. data/lib/resto/property.rb +50 -0
  13. data/lib/resto/property/handler.rb +57 -0
  14. data/lib/resto/property/integer.rb +29 -0
  15. data/lib/resto/property/string.rb +19 -0
  16. data/lib/resto/property/time.rb +43 -0
  17. data/lib/resto/request/base.rb +88 -0
  18. data/lib/resto/request/factory.rb +66 -0
  19. data/lib/resto/request/header.rb +58 -0
  20. data/lib/resto/request/option.rb +126 -0
  21. data/lib/resto/request/uri.rb +50 -0
  22. data/lib/resto/response/base.rb +85 -0
  23. data/lib/resto/translator/request_factory.rb +44 -0
  24. data/lib/resto/translator/response_factory.rb +28 -0
  25. data/lib/resto/validate.rb +37 -0
  26. data/lib/resto/validate/inclusion.rb +39 -0
  27. data/lib/resto/validate/length.rb +36 -0
  28. data/lib/resto/validate/presence.rb +24 -0
  29. data/lib/resto/version.rb +5 -0
  30. data/resto.gemspec +43 -0
  31. data/spec/resto/extra/copy_spec.rb +58 -0
  32. data/spec/resto/extra/hash_args_spec.rb +71 -0
  33. data/spec/resto/format/default_spec.rb +24 -0
  34. data/spec/resto/format/json_spec.rb +29 -0
  35. data/spec/resto/format/plain_spec.rb +21 -0
  36. data/spec/resto/format/xml_spec.rb +105 -0
  37. data/spec/resto/property/handler_spec.rb +57 -0
  38. data/spec/resto/property/integer_spec.rb +67 -0
  39. data/spec/resto/property/time_spec.rb +124 -0
  40. data/spec/resto/property_spec.rb +60 -0
  41. data/spec/resto/request/base_spec.rb +253 -0
  42. data/spec/resto/request/factory_spec.rb +114 -0
  43. data/spec/resto/translator/response_factory_spec.rb +93 -0
  44. data/spec/resto/validate/presence_spec.rb +102 -0
  45. data/spec/resto_spec.rb +531 -0
  46. data/spec/spec_helper.rb +119 -0
  47. metadata +48 -3
@@ -0,0 +1,114 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'resto/request/base'
5
+
6
+ describe Resto::Request::Factory do
7
+
8
+ let(:factory) { Resto::Request::Factory }
9
+ let(:base) { Resto::Request::Base.new }
10
+
11
+ subject do
12
+ factory.new(base
13
+ .host('sr.se')
14
+ .port(8080)
15
+ .headers('content-type' => 'text/html')
16
+ .body('Anders')
17
+ .path('/dashboard'))
18
+ end
19
+
20
+ describe "#head" do
21
+ before do
22
+ stub_request(:head, "sr.se:8080/dashboard")
23
+ .with(:headers => headers("content-type" => "text/html"))
24
+ .to_return(:status => 200)
25
+ end
26
+
27
+ it { subject.head.code.should == "200" }
28
+ end
29
+
30
+ describe "#get" do
31
+ before do
32
+ stub_request(:get, "sr.se:8080/dashboard")
33
+ .with(:headers => headers("content-type" => "text/html"))
34
+ .to_return(:status => 200)
35
+ end
36
+
37
+ it { subject.get.code.should == "200" }
38
+ end
39
+
40
+ describe "#post" do
41
+ before do
42
+ stub_request(:post, "sr.se:8080/dashboard")
43
+ .with(:headers => headers("content-type" => "text/html"),
44
+ :body => 'Anders')
45
+ .to_return(:status => 200)
46
+ end
47
+
48
+ it { subject.post.code.should == "200" }
49
+ end
50
+
51
+ describe "#put" do
52
+ before do
53
+ stub_request(:put, "sr.se:8080/dashboard")
54
+ .with(:headers => headers("content-type" => "text/html"),
55
+ :body => 'Anders')
56
+ .to_return(:status => 200)
57
+ end
58
+
59
+ it { subject.put.code.should == "200" }
60
+ end
61
+
62
+ describe "#delete" do
63
+ before do
64
+ stub_request(:delete, "sr.se:8080/dashboard")
65
+ .with(:headers => headers("content-type" => "text/html"))
66
+ .to_return(:status => 200)
67
+ end
68
+
69
+ it { subject.delete.code.should == "200" }
70
+
71
+ end
72
+
73
+ context "other settings" do
74
+ subject do
75
+ factory.new(Resto::Request::Base.new
76
+ .host('sr.se')
77
+ .path('/friends_timeline')
78
+ .body('Anders')
79
+ .headers('content-type' => 'application/xml')
80
+ .basic_auth(:username => 'developer', :password => 'secret'))
81
+ end
82
+
83
+ describe "#head" do
84
+ before do
85
+ stub_request(:head, "developer:secret@sr.se/friends_timeline")
86
+ .with(:headers => headers("content-type" => "application/xml"))
87
+ .to_return(:status => 200)
88
+ end
89
+
90
+ it { subject.head.code.should == "200" }
91
+ end
92
+
93
+ describe "#get" do
94
+ before do
95
+ stub_request(:get, "developer:secret@sr.se/friends_timeline")
96
+ .with(:headers => headers("content-type" => "application/xml"))
97
+ .to_return(:status => 200)
98
+ end
99
+
100
+ it { subject.get.code.should == "200" }
101
+ end
102
+
103
+ describe "#post" do
104
+ before do
105
+ stub_request(:post, "developer:secret@sr.se/friends_timeline")
106
+ .with(:headers => headers("content-type" => "application/xml"),
107
+ :body => 'Anders')
108
+ .to_return(:status => 200)
109
+ end
110
+
111
+ it { subject.post.code.should == "200" }
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,93 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ class A
6
+ include Resto
7
+
8
+ property :title, String
9
+ property :body, String
10
+ property :number, Integer, :remote_name => 'very_long_number_name'
11
+ end
12
+
13
+ class Translator
14
+ def call(klass, hash)
15
+ klass.new(hash[:article])
16
+ end
17
+ end
18
+
19
+ describe Resto::Translator::ResponseFactory do
20
+
21
+ context ".create([:root, :article])" do
22
+ describe "#call(klass, hash)" do
23
+
24
+ let(:factory) do
25
+ Resto::Translator::ResponseFactory.create([:root, :article])
26
+ end
27
+
28
+ hash = { :root => {
29
+ :article => {
30
+ :body => 'This is a very good article',
31
+ :title => 'Very interesting subject',
32
+ 'very_long_number_name' => '500' } } }
33
+
34
+ subject { factory.call(A, hash) }
35
+
36
+ it { should be_instance_of(A) }
37
+
38
+ its(:attributes) do
39
+ should == { :body => 'This is a very good article',
40
+ :title => 'Very interesting subject',
41
+ :number => 500 }
42
+ end
43
+ its(:number) { should == 500 }
44
+ its(:title) { should == 'Very interesting subject' }
45
+ its(:body) { should == 'This is a very good article' }
46
+ end
47
+ end
48
+
49
+ context ".create(Translator)" do
50
+ describe "#call(klass, hash)" do
51
+
52
+ let(:factory) { Resto::Translator::ResponseFactory.create(Translator) }
53
+
54
+ hash = { :article => {
55
+ :body => 'This is a very good articel',
56
+ :title => 'Very interesting subject' } }
57
+
58
+ subject { factory.call(A, hash) }
59
+
60
+ it { should be_instance_of(A) }
61
+ its(:attributes) do
62
+ should == { :body => 'This is a very good articel',
63
+ :title => 'Very interesting subject' }
64
+ end
65
+ end
66
+ end
67
+
68
+ context ".create(:default)" do
69
+ describe "#call(klass, hash)" do
70
+
71
+ let(:factory) { Resto::Translator::ResponseFactory.create(:default) }
72
+
73
+ hash = { :body => 'This is a very good articel',
74
+ :title => 'Very interesting subject' }
75
+
76
+ subject { factory.call(A, hash) }
77
+
78
+ it { should be_instance_of(A) }
79
+ its(:attributes) do
80
+ should == { :body => 'This is a very good articel',
81
+ :title => 'Very interesting subject' }
82
+ end
83
+ end
84
+ end
85
+
86
+ describe ".create(:invalid_symbol)" do
87
+ it "raises ArgumentError when invalid argument" do
88
+ lambda do
89
+ Resto::Translator::ResponseFactory.create(:invalid_symbol)
90
+ end.should raise_error(ArgumentError)
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ class Article
5
+ def initialize; @errors = {}; end
6
+ def title_without_cast; " 200 "; end
7
+ def empty_title_without_cast; " "; end
8
+ def nil_title_without_cast; end
9
+
10
+ def errors; @errors; end
11
+ def add_error(key, error); @errors.store(key, error); end
12
+
13
+ def false; false; end
14
+ def true; true; end
15
+ end
16
+
17
+ describe Resto::Validate::Presence do
18
+ let(:article) { Article.new }
19
+
20
+ context "Resto::Validate::Presence.new" do
21
+ let(:validate) { Resto::Validate::Presence.new }
22
+
23
+ before do
24
+ validate.attribute_value(article, :title)
25
+ validate.attribute_value(article, :empty_title)
26
+ validate.attribute_value(article, :nil_title)
27
+ end
28
+
29
+ context "errors" do
30
+ let(:errors) { article.errors }
31
+
32
+ it { errors[:title_presence].should == nil }
33
+ it {
34
+ errors[:empty_title_presence].should == ":empty_title can’t be blank"
35
+ }
36
+ it { errors[:nil_title_presence].should == ":nil_title can’t be blank" }
37
+ end
38
+ end
39
+
40
+
41
+ context "Resto::Validate::Presence.new .message 'must have a value' " do
42
+ let(:validate) { Resto::Validate::Presence.new.message 'must have a value' }
43
+
44
+ before do
45
+ validate.attribute_value(article, :title)
46
+ validate.attribute_value(article, :empty_title)
47
+ validate.attribute_value(article, :nil_title)
48
+ end
49
+
50
+ context "errors" do
51
+ let(:errors) { article.errors }
52
+
53
+ it { errors[:title_presence].should == nil }
54
+ it {
55
+ errors[:empty_title_presence].should == ":empty_title must have a value"
56
+ }
57
+ it {
58
+ errors[:nil_title_presence].should == ":nil_title must have a value"
59
+ }
60
+ end
61
+ end
62
+
63
+ context "Resto::Validate::Presence.new .if { |resource| resource.false }" do
64
+ let(:validate) do
65
+ Resto::Validate::Presence.new .if { |article| article.false }
66
+ end
67
+
68
+ before do
69
+ validate.attribute_value(article, :title)
70
+ validate.attribute_value(article, :empty_title)
71
+ validate.attribute_value(article, :nil_title)
72
+ end
73
+
74
+ context "errors" do
75
+ let(:errors) { article.errors }
76
+
77
+ it { errors[:title_presence].should == nil }
78
+ it { errors[:empty_title_presence].should == nil }
79
+ it { errors[:nil_title_presence].should == nil }
80
+ end
81
+ end
82
+
83
+ context "Resto::Validate::Presence.new.unless { |resource| resource.true }" do
84
+ let(:validate) do
85
+ Resto::Validate::Presence.new .unless { |article| article.true }
86
+ end
87
+
88
+ before do
89
+ validate.attribute_value(article, :title)
90
+ validate.attribute_value(article, :empty_title)
91
+ validate.attribute_value(article, :nil_title)
92
+ end
93
+
94
+ context "errors" do
95
+ let(:errors) { article.errors }
96
+
97
+ it { errors[:title_presence].should == nil }
98
+ it { errors[:empty_title_presence].should == nil }
99
+ it { errors[:nil_title_presence].should == nil }
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,531 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Resto do
6
+ class_context(%Q{
7
+ class Subscription
8
+ include Resto
9
+
10
+ resource_identifier :id
11
+ property :id, Integer
12
+ property :product_id, Integer
13
+ property :customer_id, Integer
14
+ property :cancellation_message, String
15
+ property :state, String
16
+
17
+ resto_request do
18
+ format :json, :extension => true
19
+ basic_auth(:username => 'EyphE_t',
20
+ :password => 'x')
21
+
22
+ host 'https://dns-parrot.chargify.com/'
23
+ path '/subscriptions'
24
+ translator [:subscription]
25
+ end
26
+
27
+ resto_response do
28
+ format :json
29
+ translator [:subscription]
30
+ end
31
+ end}) do
32
+
33
+ let(:attributes) do
34
+ { :id => 415520,
35
+ :product_id => 25450,
36
+ :customer_id => 416942,
37
+ :cancellation_message => 'The reason',
38
+ :state =>"canceled"
39
+ }
40
+ end
41
+
42
+ let(:body) do
43
+ { :subscription => attributes.merge({}).keep_if { |k, _| k != :id } }
44
+ end
45
+
46
+ let(:response) do
47
+ { :subscription => attributes }
48
+ end
49
+
50
+ describe ".all" do
51
+ before do
52
+ stub_request(:get,
53
+ "https://EyphE_t:x@dns-parrot.chargify.com/subscriptions.json")
54
+ .with(:headers => headers('accept' => 'application/json, */*',
55
+ 'content-type' => 'application/json'))
56
+ .to_return(:status => 200, :body => [response].to_json)
57
+ end
58
+
59
+ subject { Subscription.all.first }
60
+
61
+ it { should be_instance_of(Subscription) }
62
+ its(:id) { should == 415520 }
63
+ its(:product_id) { should == 25450 }
64
+ its(:customer_id) { should == 416942 }
65
+ its(:cancellation_message) { should == 'The reason' }
66
+ its(:state) { should == 'canceled' }
67
+ it { should be_valid }
68
+ end
69
+
70
+ describe ".get(id)" do
71
+ before do
72
+ stub_request(:get,
73
+ "https://EyphE_t:x@dns-parrot.chargify.com/subscriptions/415520.json")
74
+ .with(:headers => headers('accept' => 'application/json, */*',
75
+ 'content-type' => 'application/json'))
76
+ .to_return(:status => 200, :body => response.to_json)
77
+ end
78
+
79
+ subject { Subscription.get(415520) }
80
+
81
+ it { should be_instance_of(Subscription) }
82
+ its(:id) { should == 415520 }
83
+ its(:product_id) { should == 25450 }
84
+ its(:customer_id) { should == 416942 }
85
+ its(:cancellation_message) { should == 'The reason' }
86
+ its(:state) { should == 'canceled' }
87
+ it { should be_valid }
88
+ end
89
+
90
+ describe "#get" do
91
+ before do
92
+ stub_request(:get,
93
+ "https://EyphE_t:x@dns-parrot.chargify.com/subscriptions/415520.json")
94
+ .with(:headers => headers('accept' => 'application/json, */*',
95
+ 'content-type' => 'application/json'))
96
+ .to_return(:status => 200, :body => response.to_json)
97
+ end
98
+
99
+ subject { Subscription.new(attributes).get }
100
+
101
+ it { should be_instance_of(Subscription) }
102
+ its(:id) { should == 415520 }
103
+ its(:product_id) { should == 25450 }
104
+ its(:customer_id) { should == 416942 }
105
+ its(:cancellation_message) { should == 'The reason' }
106
+ its(:state) { should == 'canceled' }
107
+ it { should be_valid }
108
+ end
109
+
110
+ describe "#reload" do
111
+ before do
112
+ stub_request(:get,
113
+ "https://EyphE_t:x@dns-parrot.chargify.com/subscriptions/415520.json")
114
+ .with(:headers => headers('accept' => 'application/json, */*',
115
+ 'content-type' => 'application/json'))
116
+ .to_return(:status => 200, :body => response.to_json)
117
+ end
118
+
119
+ subject { Subscription.new(attributes).reload }
120
+
121
+ it { should be_instance_of(Subscription) }
122
+ its(:id) { should == 415520 }
123
+ its(:product_id) { should == 25450 }
124
+ its(:customer_id) { should == 416942 }
125
+ its(:cancellation_message) { should == 'The reason' }
126
+ its(:state) { should == 'canceled' }
127
+ it { should be_valid }
128
+ end
129
+
130
+ describe ".post(attributes)" do
131
+ before do
132
+ stub_request(:post,
133
+ "https://EyphE_t:x@dns-parrot.chargify.com/subscriptions.json")
134
+ .with(:headers => headers('accept' => 'application/json, */*',
135
+ 'content-type' => 'application/json'),
136
+ :body => body.to_json)
137
+ .to_return(:status => 201, :body => response.to_json)
138
+ end
139
+
140
+ subject { Subscription.post(attributes) }
141
+
142
+ it { should be_instance_of(Subscription) }
143
+ its(:id) { should == 415520 }
144
+ its(:product_id) { should == 25450 }
145
+ its(:customer_id) { should == 416942 }
146
+ its(:cancellation_message) { should == 'The reason' }
147
+ its(:state) { should == 'canceled' }
148
+ it { should be_valid }
149
+ end
150
+
151
+ describe ".put(attributes)" do
152
+ before do
153
+ stub_request(:put,
154
+ "https://EyphE_t:x@dns-parrot.chargify.com/subscriptions/415520.json")
155
+ .with(:headers => headers('accept' => 'application/json, */*',
156
+ 'content-type' => 'application/json'),
157
+ :body => body.to_json)
158
+ .to_return(:status => 200, :body => response.to_json)
159
+ end
160
+
161
+ subject { Subscription.put(attributes) }
162
+
163
+ it { should be_instance_of(Subscription) }
164
+ its(:id) { should == 415520 }
165
+ its(:product_id) { should == 25450 }
166
+ its(:customer_id) { should == 416942 }
167
+ its(:cancellation_message) { should == 'The reason' }
168
+ its(:state) { should == 'canceled' }
169
+ it { should be_valid }
170
+ end
171
+
172
+ describe "#put" do
173
+ before do
174
+ stub_request(:put,
175
+ "https://EyphE_t:x@dns-parrot.chargify.com/subscriptions/415520.json")
176
+ .with(:headers => headers('accept' => 'application/json, */*',
177
+ 'content-type' => 'application/json'),
178
+ :body => body.to_json)
179
+ .to_return(:status => 200, :body => response.to_json)
180
+ end
181
+
182
+ subject { Subscription.new(attributes).put }
183
+
184
+ it { should be_instance_of(Subscription) }
185
+ its(:id) { should == 415520 }
186
+ its(:product_id) { should == 25450 }
187
+ its(:customer_id) { should == 416942 }
188
+ its(:cancellation_message) { should == 'The reason' }
189
+ its(:state) { should == 'canceled' }
190
+ it { should be_valid }
191
+ end
192
+
193
+ describe ".delete(id)" do
194
+ before do
195
+ stub_request(:delete,
196
+ "https://EyphE_t:x@dns-parrot.chargify.com/subscriptions/415520.json")
197
+ .with(:headers => headers('accept' => 'application/json, */*',
198
+ 'content-type' => 'application/json'))
199
+ .to_return(:status => 200)
200
+ end
201
+
202
+ subject { Subscription.delete(415520) }
203
+
204
+ it { should be_instance_of(Subscription) }
205
+ it { should be_valid }
206
+ end
207
+
208
+ describe "#delete" do
209
+ before do
210
+ stub_request(:delete,
211
+ "https://EyphE_t:x@dns-parrot.chargify.com/subscriptions/415520.json")
212
+ .with(:headers => headers('accept' => 'application/json, */*',
213
+ 'content-type' => 'application/json'))
214
+ .to_return(:status => 200)
215
+ end
216
+
217
+ subject { Subscription.new(attributes).delete }
218
+
219
+ it { should be_instance_of(Subscription) }
220
+ it { should be_valid }
221
+ its(:id) { should be_nil }
222
+ end
223
+
224
+ describe "#update_attributes(attributes)" do
225
+ subject do
226
+ Subscription.new(attributes).update_attributes(:state => "updated")
227
+ end
228
+
229
+ its(:state) { should == "updated" }
230
+ end
231
+
232
+ describe "#body(attributes)" do
233
+ subject do
234
+ Subscription.new(attributes).body(:state => "updated")
235
+ end
236
+
237
+ its(:state) { should == "updated" }
238
+ end
239
+
240
+ end
241
+
242
+ class_context(%Q{
243
+ class RestUser
244
+ include Resto
245
+
246
+ property :id, Integer
247
+ property :title, String
248
+ property :body, String, :remote_name => 'a_bad_body_name' do
249
+ validate_presence .if { |user| user.title.to_s.size < 3 }
250
+ .message 'must be present'
251
+ end
252
+
253
+ resto_request do
254
+ host 'http://api.bit.ly'
255
+ path '/v3/users'
256
+ format :json
257
+ end
258
+
259
+ resto_response do
260
+ format :json
261
+ translator [:root, :user]
262
+ end
263
+ end}) do
264
+
265
+ describe ".new" do
266
+ it { RestUser.new({:name => 'Anders'}).should be_instance_of(RestUser) }
267
+ end
268
+
269
+ describe ".get(id)" do
270
+ let(:request) do
271
+ stub_request(:get, "http://api.bit.ly/v3/users/200")
272
+ .with(:headers => headers('accept'=>'application/json, */*',
273
+ 'content-type'=>'application/json'))
274
+ end
275
+
276
+ subject { RestUser.get(200) }
277
+
278
+ context "response with valid body attribute" do
279
+ before do
280
+ body = {:root => { :user => {'a_bad_body_name' => 'Content',
281
+ 'title' => 'Read this',
282
+ 'id' => '100' } } }
283
+ request.to_return(:status => 200, :body => body.to_json)
284
+ end
285
+
286
+ it { should be_instance_of(RestUser) }
287
+ its(:id) { should == 100 }
288
+ its(:title) { should == 'Read this' }
289
+ its(:body) { should == 'Content' }
290
+ it { should be_valid }
291
+ end
292
+
293
+ context "response with invalid body attribute" do
294
+ before do
295
+ request.to_return(:status => 200, :body => {}.to_json)
296
+ subject.valid?
297
+ end
298
+
299
+ it { should be_instance_of(RestUser ) }
300
+ its(:id) { should == nil }
301
+ its(:title) { should == nil }
302
+ its(:body) { should == nil }
303
+ it { should_not be_valid }
304
+ its(:errors) { should == [":body must be present"] }
305
+ end
306
+ end
307
+ end
308
+
309
+ class_context(%{
310
+ class RestArticle
311
+ include Resto
312
+
313
+ resto_request do
314
+ host 'http://api.bit.ly'
315
+ path '/v3/articles'
316
+ format :json
317
+ end
318
+
319
+ resto_response do
320
+ format :json
321
+ end
322
+ end}) do
323
+
324
+ describe ".all" do
325
+ before do
326
+ stub_request(:get, "http://api.bit.ly/v3/articles")
327
+ .with(:headers => headers('accept'=>'application/json, */*',
328
+ 'content-type'=>'application/json'))
329
+ .to_return(:status => 200)
330
+ end
331
+
332
+ it { RestArticle.all.code.should == "200" }
333
+ end
334
+
335
+ describe ".all('tag' => 'resto')" do
336
+ before do
337
+ stub_request(:get, "http://api.bit.ly/v3/articles?tag=resto")
338
+ .with(:headers => headers('accept'=>'application/json, */*',
339
+ 'content-type'=>'application/json'))
340
+ .to_return(:status => 200)
341
+ end
342
+
343
+ it { RestArticle.all('tag' => 'resto').code.should == "200" }
344
+ end
345
+
346
+ describe ".head" do
347
+ before do
348
+ stub_request(:head, "http://api.bit.ly/v3/articles")
349
+ .with(:headers => headers('accept'=>'application/json, */*',
350
+ 'content-type'=>'application/json'))
351
+ .to_return(:status => 200)
352
+ end
353
+
354
+ it { RestArticle.head.code.should == "200" }
355
+ end
356
+
357
+ describe ".get(200)" do
358
+ before do
359
+ stub_request(:get, "http://api.bit.ly/v3/articles/200")
360
+ .with(:headers => headers('accept'=>'application/json, */*',
361
+ 'content-type'=>'application/json'))
362
+ .to_return(:status => 200)
363
+ end
364
+
365
+ it { RestArticle.get(200).code.should == "200" }
366
+ end
367
+
368
+ describe ".post(:author => 'Anders')" do
369
+ before do
370
+ stub_request(:post, "http://api.bit.ly/v3/articles")
371
+ .with(:body => { "author" => "Anders"}.to_json,
372
+ :headers => headers('accept'=>'application/json, */*',
373
+ 'content-type'=>'application/json'))
374
+ .to_return(:status => 200)
375
+ end
376
+
377
+ it { RestArticle.post(:author => 'Anders').code.should == "200" }
378
+ end
379
+
380
+ describe ".put(:author => 'Anders')" do
381
+ before do
382
+ stub_request(:put, "http://api.bit.ly/v3/articles")
383
+ .with(:body => { "author"=> "Anders"}.to_json,
384
+ :headers => headers('accept'=>'application/json, */*',
385
+ 'content-type'=>'application/json'))
386
+ .to_return(:status => 200)
387
+ end
388
+
389
+ it { RestArticle.put(:author => 'Anders').code.should == "200" }
390
+ end
391
+
392
+ describe ".delete(400)" do
393
+ before do
394
+ stub_request(:delete, "http://api.bit.ly/v3/articles/400")
395
+ .with(:headers => headers('accept'=>'application/json, */*',
396
+ 'content-type'=>'application/json'))
397
+ .to_return(:status => 200)
398
+ end
399
+
400
+ it { RestArticle.delete(400).code.should == "200" }
401
+ end
402
+ end
403
+
404
+ class_context(%Q{
405
+ class RestArticleWithExtension
406
+ include Resto
407
+
408
+ resto_request do
409
+ host 'http://api.bit.ly'
410
+ path '/v3/articles'
411
+ format :json, :extension => :true
412
+ end
413
+
414
+ end}) do
415
+
416
+ describe ".all" do
417
+ before do
418
+ stub_request(:get, "http://api.bit.ly/v3/articles.json")
419
+ .with(:headers => headers('accept'=>'application/json, */*',
420
+ 'content-type'=>'application/json'))
421
+ .to_return(:status => 200)
422
+ end
423
+
424
+ it { RestArticleWithExtension.all.code.should == "200" }
425
+ end
426
+
427
+ describe ".all('tag' => 'resto')" do
428
+ before do
429
+ stub_request(:get, "http://api.bit.ly/v3/articles.json?tag=resto")
430
+ .with(:headers => headers('accept'=>'application/json, */*',
431
+ 'content-type'=>'application/json'))
432
+ .to_return(:status => 200)
433
+ end
434
+
435
+ it { RestArticleWithExtension.all('tag' => 'resto').code.should == "200" }
436
+ end
437
+
438
+ describe ".head" do
439
+ before do
440
+ stub_request(:head, "http://api.bit.ly/v3/articles.json")
441
+ .with(:headers => headers('accept'=>'application/json, */*',
442
+ 'content-type'=>'application/json'))
443
+ .to_return(:status => 200)
444
+ end
445
+
446
+ it { RestArticleWithExtension.head.code.should == "200" }
447
+ end
448
+
449
+ describe ".get(200)" do
450
+ before do
451
+ stub_request(:get, "http://api.bit.ly/v3/articles/200.json")
452
+ .with(:headers => headers('accept'=>'application/json, */*',
453
+ 'content-type'=>'application/json'))
454
+ .to_return(:status => 200)
455
+ end
456
+
457
+ it { RestArticleWithExtension.get(200).code.should == "200" }
458
+ end
459
+
460
+ describe ".post(:author => 'Anders')" do
461
+ before do
462
+ stub_request(:post, "http://api.bit.ly/v3/articles.json")
463
+ .with(:body => { "author" => "As" }.to_json,
464
+ :headers => headers('accept'=>'application/json, */*',
465
+ 'content-type'=>'application/json'))
466
+ .to_return(:status => 200)
467
+ end
468
+
469
+ it { RestArticleWithExtension.post(:author => 'As').code.should == "200" }
470
+ end
471
+
472
+ describe ".put(:author => 'Anders')" do
473
+ before do
474
+ stub_request(:put, "http://api.bit.ly/v3/articles.json")
475
+ .with(:body => { "author" => "An" }.to_json,
476
+ :headers => headers('accept'=>'application/json, */*',
477
+ 'content-type'=>'application/json'))
478
+ .to_return(:status => 200)
479
+ end
480
+
481
+ it { RestArticleWithExtension.put(:author => 'An').code.should == "200" }
482
+ end
483
+
484
+ describe ".delete(400)" do
485
+ before do
486
+ stub_request(:delete, "http://api.bit.ly/v3/articles/400.json")
487
+ .with(:headers => headers('accept'=>'application/json, */*',
488
+ 'content-type'=>'application/json'))
489
+ .to_return(:status => 200)
490
+ end
491
+
492
+ it { RestArticleWithExtension.delete(400).code.should == "200" }
493
+ end
494
+ end
495
+
496
+ class_context(%Q{
497
+ class Bitly
498
+ include Resto
499
+
500
+ resto_request do
501
+ headers "content-type" => "text/html"
502
+ host 'http://bit.ly'
503
+ path '/v3'
504
+ query "format=json"
505
+ params "longUrl" => "ll"
506
+ end
507
+
508
+ end}) do
509
+
510
+ describe ".all()" do
511
+ before do
512
+ stub_request(:get, "http://bit.ly/v3?format=json&longUrl=ll")
513
+ .with(:headers => headers("content-type" => "text/html"))
514
+ .to_return(:status => 200)
515
+ end
516
+
517
+ it { Bitly.all.code.should == "200" }
518
+ end
519
+
520
+ describe ".all('shortUrl' => short)" do
521
+ before do
522
+ stub_request(:get, "http://bit.ly/v3?format=json&shortUrl=short")
523
+ .with(:headers => headers("content-type" => "text/html"))
524
+ .to_return(:status => 200)
525
+ end
526
+
527
+ it { Bitly.all('shortUrl' => 'short').code.should == "200" }
528
+ end
529
+ end
530
+
531
+ end