resto 0.0.3 → 0.0.4

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 (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