bubble-wrap 1.5.0 → 1.6.0.rc1

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.
@@ -1,32 +0,0 @@
1
- # Response class wrapping the results of a Query's response
2
- module BubbleWrap; module HTTP; class Response
3
- attr_reader :body
4
- attr_reader :headers
5
- attr_accessor :status_code, :status_description, :error_message, :error
6
- attr_reader :url
7
- attr_reader :original_url
8
-
9
- def initialize(values={})
10
- self.update(values)
11
- end
12
-
13
- def update(values)
14
- values.each do |k,v|
15
- self.instance_variable_set("@#{k}", v)
16
- end
17
- update_status_description
18
- end
19
-
20
- def ok?
21
- status_code.to_s =~ /2\d\d/ ? true : false
22
- end
23
-
24
- def to_s
25
- "#<#{self.class}:#{self.object_id} - url: #{self.url}, body: #{self.body}, headers: #{self.headers}, status code: #{self.status_code}, error message: #{self.error_message} >"
26
- end
27
- alias description to_s
28
-
29
- def update_status_description
30
- @status_description = status_code.nil? ? nil : NSHTTPURLResponse.localizedStringForStatusCode(status_code)
31
- end
32
- end; end; end
@@ -1,808 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- describe BubbleWrap::HTTP::Query do
3
-
4
- describe "json parameter encoding" do
5
- before do
6
- @json_payload = {"foo" => "bar"}
7
- @json_options = {
8
- payload: @json_payload,
9
- format: :json
10
- }
11
- @json_query = BubbleWrap::HTTP::Query.new( "http://localhost:3000" , :post, @json_options )
12
- end
13
-
14
- it "should generate json body" do
15
- BW::JSON.parse(@json_query.request.HTTPBody).should == @json_payload
16
- end
17
- end
18
-
19
- describe "false value" do
20
- before do
21
- @query = BubbleWrap::HTTP::Query.new("http://www.google.com", :get, {payload: {following: false}})
22
- end
23
-
24
- it "should have right url" do
25
- @query.request.URL.absoluteString.should == "http://www.google.com?following=false"
26
- end
27
- end
28
-
29
- before do
30
- @localhost_url = 'http://localhost'
31
- @fake_url = 'http://fake.url'
32
-
33
- @credentials = { username: 'mneorr', password: '123456xx!@crazy' }
34
- @credential_persistence = 0
35
- @payload = {
36
- user: { name: 'marin', surname: 'usalj' },
37
- twitter: '@mneorr',
38
- website: 'mneorr.com',
39
- values: ['apple', 'orange', 'peach'],
40
- credentials: @credentials
41
- }
42
- @action = Proc.new { |response| @real_response = response; @delegator_was_called = true }
43
- @format = "application/x-www-form-urlencoded"
44
- @cache_policy = 24234
45
- @leftover_option = 'trololo'
46
- @headers = { 'User-Agent' => "Mozilla/5.0 (X11; Linux x86_64; rv:12.0) \n Gecko/20100101 Firefox/12.0" }
47
- @files = {
48
- fake_file: NSJSONSerialization.dataWithJSONObject({ fake: 'json' }, options:0, error:nil),
49
- empty_file: NSMutableData.data
50
- }
51
- @options = {
52
- action: @action,
53
- files: @files,
54
- payload: @payload,
55
- credentials: @credentials,
56
- credential_persistence: @credential_persistence,
57
- headers: @headers,
58
- cache_policy: @cache_policy,
59
- leftover_option: @leftover_option,
60
- format: @format
61
- }
62
- @query = BubbleWrap::HTTP::Query.new( @localhost_url , :get, @options )
63
- end
64
-
65
- it "has appropriate attributes" do
66
- @query.should.respond_to :request=
67
- @query.should.respond_to :connection=
68
- @query.should.respond_to :credentials=
69
- @query.should.respond_to :proxy_credential=
70
- @query.should.respond_to :post_data=
71
-
72
- @query.should.respond_to :method
73
- @query.should.respond_to :response
74
- @query.should.respond_to :status_code
75
- @query.should.respond_to :response_headers
76
- @query.should.respond_to :response_size
77
- @query.should.respond_to :options
78
- end
79
-
80
- it "should accept nil header value" do
81
- @headers = { 'Authorization' => nil, 'User-Agent' => "Mozilla/5.0 (X11; Linux x86_64; rv:12.0) \n Gecko/20100101 Firefox/12.0" }
82
- @options = {
83
- headers: @headers,
84
- }
85
- query = BubbleWrap::HTTP::Query.new( @localhost_url , :get, @options )
86
- query.should.not.be.nil
87
- end
88
-
89
- describe "When initialized" do
90
-
91
- it "should upcase the HTTP method" do
92
- @query.method.should.equal "GET"
93
- end
94
-
95
- it "throws an error for invalid/missing URL schemes" do
96
- %w(http https file ftp).each do |scheme|
97
- lambda {
98
- BW::HTTP::Query.new("#{scheme}://example.com", :get) { |r| p r.body.to_str }
99
- }.should.not.raise InvalidURLError
100
- end
101
-
102
- lambda {
103
- BW::HTTP::Query.new("bad://example.com", :get) { |r| p r.body.to_str }
104
- }.should.raise InvalidURLError
105
- end
106
-
107
- it "should set the deleted delegator from options" do
108
- @query.instance_variable_get(:@delegator).should.equal @action
109
- @options.should.not.has_key? :action
110
- end
111
-
112
- it "sets the files to instance variable" do
113
- @query.instance_variable_get(:@files).should.equal @files
114
- @options.should.not.has_key? :files
115
- end
116
-
117
- it "sets the format from options" do
118
- @query.instance_variable_get(:@format).should.equal @format
119
- @options.should.not.has_key? :format
120
- end
121
-
122
- it "should set self as the delegator if action was not passed in" do
123
- new_query = BubbleWrap::HTTP::Query.new( 'http://localhost', :get, {})
124
- new_query.instance_variable_get(:@delegator).should.equal new_query
125
- end
126
-
127
- it "should merge :username and :password in loaded credentials" do
128
- @query.credentials.should.equal @credentials
129
-
130
- options = { credentials: {} }
131
- new_query = BubbleWrap::HTTP::Query.new( @localhost_url, :get, options)
132
-
133
- generated_credentials = { :username => nil, :password => nil }
134
- new_query.credentials.should.equal generated_credentials
135
- options.should.be.empty
136
- end
137
-
138
-
139
- describe "PAYLOAD / UPLOAD FILES" do
140
-
141
- def create_query(payload, files)
142
- BubbleWrap::HTTP::Query.new( 'http://haha', :post, { payload: payload, files: files } )
143
- end
144
-
145
- def sample_data
146
- "twitter:@mneorr".dataUsingEncoding NSUTF8StringEncoding
147
- end
148
-
149
- it "should set payload from options{} to @payload" do
150
- payload = "user%5Bname%5D=marin&user%5Bsurname%5D=usalj&twitter=%40mneorr&website=mneorr.com&values%5B%5D=apple&values%5B%5D=orange&values%5B%5D=peach&credentials%5Busername%5D=mneorr&credentials%5Bpassword%5D=123456xx%21%40crazy"
151
- @query.instance_variable_get(:@payload).should.equal payload
152
- @options.should.not.has_key? :payload
153
- end
154
-
155
- it "should check if @payload is a hash before generating GET params" do
156
- query_string_payload = BubbleWrap::HTTP::Query.new( @fake_url , :get, { payload: "name=apple&model=macbook"} )
157
- query_string_payload.instance_variable_get(:@payload).should.equal 'name=apple&model=macbook'
158
- end
159
-
160
- it "should check if payload is nil" do
161
- lambda{
162
- BubbleWrap::HTTP::Query.new( @fake_url , :post, {} )
163
- }.should.not.raise NoMethodError
164
- end
165
-
166
- it "should set the payload in URL only for GET/HEAD/OPTIONS requests" do
167
- [:post, :put, :delete, :patch].each do |method|
168
- query = BubbleWrap::HTTP::Query.new( @localhost_url , method, { payload: @payload } )
169
- query.instance_variable_get(:@url).description.should.equal @localhost_url
170
- end
171
-
172
- payload = {name: 'marin'}
173
- [:get, :head, :options].each do |method|
174
- query = BubbleWrap::HTTP::Query.new( @localhost_url , method, { payload: payload } )
175
- query.instance_variable_get(:@url).description.should.equal "#{@localhost_url}?name=marin"
176
- end
177
- end
178
-
179
- it "processes filenames from file hashes" do
180
- files = {
181
- upload: {data: sample_data, filename: "test.txt"}
182
- }
183
- query = BubbleWrap::HTTP::Query.new(@fake_url, :post, {files: files})
184
- uuid = query.instance_variable_get(:@boundary)
185
- real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding)
186
- real_payload.should.equal "--#{uuid}\r\nContent-Disposition: attachment; name=\"upload\"; filename=\"test.txt\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}--\r\n"
187
- end
188
-
189
- it "processes filenames from file hashes, using the name when the filename is missing" do
190
- files = {
191
- upload: {data: sample_data}
192
- }
193
- query = BubbleWrap::HTTP::Query.new(@fake_url, :post, {files: files})
194
- uuid = query.instance_variable_get(:@boundary)
195
- real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding)
196
- real_payload.should.equal "--#{uuid}\r\nContent-Disposition: attachment; name=\"upload\"; filename=\"upload\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}--\r\n"
197
- end
198
-
199
- it "throws an error for invalid file parameters" do
200
- files = {
201
- twitter: {filename: "test.txt", data: nil}
202
- }
203
- lambda {
204
- BW::HTTP::Query.new("http://example.com", :post, { files: files})
205
- }.should.raise InvalidFileError
206
- end
207
-
208
- it "sets the HTTPBody DATA to @request for all methods except GET/HEAD/OPTIONS" do
209
- payload = { name: 'apple', model: 'macbook'}
210
- files = { twitter: sample_data, site: "mneorr.com".dataUsingEncoding(NSUTF8StringEncoding) }
211
-
212
- [:post, :put, :delete, :patch].each do |method|
213
- puts " - #{method}\n"
214
- query = BubbleWrap::HTTP::Query.new( @fake_url , method, { payload: payload, files: files } )
215
- uuid = query.instance_variable_get(:@boundary)
216
- real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding)
217
- real_payload.should.equal "--#{uuid}\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\napple\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nmacbook\r\n--#{uuid}\r\nContent-Disposition: attachment; name=\"twitter\"; filename=\"twitter\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}\r\nContent-Disposition: attachment; name=\"site\"; filename=\"site\"\r\nContent-Type: application/octet-stream\r\n\r\nmneorr.com\r\n--#{uuid}--\r\n"
218
- end
219
-
220
- [:get, :head, :options].each do |method|
221
- puts " - #{method}\n"
222
- query = BubbleWrap::HTTP::Query.new( @fake_url , method, { payload: payload } )
223
- real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding)
224
- real_payload.should.be.empty
225
- end
226
- end
227
-
228
- it "sets the payload without conversion to-from NSString if the payload was NSData" do
229
- data = sample_data
230
- lambda { create_query(data, nil) }.should.not.raise NoMethodError
231
- end
232
-
233
- it "sets the payload as a string if JSON" do
234
- json = "{\"foo\":42,\"bar\":\"BubbleWrap\"}"
235
- [:put, :post, :delete, :patch].each do |method|
236
- puts " - #{method}\n"
237
- query = BubbleWrap::HTTP::Query.new( @fake_url , method, { payload: json } )
238
- set_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding)
239
- set_payload.should.equal json
240
- end
241
- end
242
-
243
- it "sets the payload for a nested hash to multiple form-data parts" do
244
- payload = { computer: { name: 'apple', model: 'macbook'} }
245
- query = BubbleWrap::HTTP::Query.new( @fake_url, :post, { payload: payload } )
246
- uuid = query.instance_variable_get(:@boundary)
247
- real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding)
248
- real_payload.should.equal "--#{uuid}\r\nContent-Disposition: form-data; name=\"computer[name]\"\r\n\r\napple\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"computer[model]\"\r\n\r\nmacbook\r\n--#{uuid}--\r\n"
249
- end
250
-
251
- [["NSUTF8StringEncoding", NSUTF8StringEncoding],
252
- ["NSJapaneseEUCStringEncoding", NSJapaneseEUCStringEncoding],
253
- ["NSShiftJISStringEncoding", NSShiftJISStringEncoding],
254
- ["NSISO2022JPStringEncoding", NSISO2022JPStringEncoding]].each do |enc_name, encoding|
255
- it "sets the japanese characters payload encoded in #{enc_name}" do
256
- payload = { computer: { name: '名前', model: 'モデル'} }
257
- query = BubbleWrap::HTTP::Query.new( @fake_url, :post, { payload: payload, encoding: encoding })
258
- uuid = query.instance_variable_get(:@boundary)
259
- real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:encoding)
260
- real_payload.should.equal "--#{uuid}\r\nContent-Disposition: form-data; name=\"computer[name]\"\r\n\r\n#{payload[:computer][:name]}\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"computer[model]\"\r\n\r\n#{payload[:computer][:model]}\r\n--#{uuid}--\r\n"
261
- end
262
- end
263
-
264
- end
265
-
266
- it "should set default timeout to 30s or the one from hash" do
267
- @query.instance_variable_get(:@timeout).should == 30
268
-
269
- options = {timeout: 10}
270
- new_query = BubbleWrap::HTTP::Query.new( @localhost_url, :get, options)
271
-
272
- new_query.instance_variable_get(:@timeout).should == 10
273
- options.should.be.empty
274
- end
275
-
276
- it "should delete :headers from options and escape Line Feeds" do
277
- escaped_lf = "Mozilla/5.0 (X11; Linux x86_64; rv:12.0) \r\n Gecko/20100101 Firefox/12.0"
278
- headers = @query.instance_variable_get(:@headers)
279
-
280
- headers["User-Agent"].should.equal escaped_lf
281
- end
282
-
283
- it "should delete :cache_policy or set NSURLRequestUseProtocolCachePolicy" do
284
- @query.instance_variable_get(:@cache_policy).should.equal @cache_policy
285
- @options.should.not.has_key? :cache_policy
286
-
287
- new_query = BubbleWrap::HTTP::Query.new( @localhost_url, :get, {})
288
- new_query.instance_variable_get(:@cache_policy).should.equal NSURLRequestUseProtocolCachePolicy
289
- end
290
-
291
- it "should delete :credential_persistence or set NSURLCredentialPersistenceForSession" do
292
- @query.instance_variable_get(:@credential_persistence).should.equal @credential_persistence
293
- @options.should.not.has_key? :credential_persistence
294
-
295
- new_query = BubbleWrap::HTTP::Query.new( @localhost_url, :get, {})
296
- new_query.instance_variable_get(:@credential_persistence).should.equal NSURLCredentialPersistenceForSession
297
- end
298
-
299
- it "should present base64-encoded credentials in Authorization header when provided" do
300
- headers = @query.instance_variable_get(:@headers)
301
-
302
- headers["Authorization"].should.equal "Basic bW5lb3JyOjEyMzQ1Nnh4IUBjcmF6eQ=="
303
- end
304
-
305
- it "should not present Authorization header when :present_credentials is false" do
306
- query = BubbleWrap::HTTP::Query.new(@fake_url, :get, { credentials: @credentials, present_credentials: false })
307
- headers = query.instance_variable_get(:@headers)
308
-
309
- headers.should.equal nil
310
- end
311
-
312
-
313
- it "should set the rest of options{} to ivar @options" do
314
- @query.options.size.should.equal 1
315
- @query.options.values[0].should.equal @leftover_option
316
- end
317
-
318
- it "should create a new response before instantiating a new request" do
319
- @query.response.should.not.equal nil
320
- end
321
-
322
- it "should call initiate_request with the URL passed in" do
323
- processed_url = "http://localhost?user%5Bname%5D=marin&user%5Bsurname%5D=usalj&twitter=%40mneorr&website=mneorr.com&values%5B%5D=apple&values%5B%5D=orange&values%5B%5D=peach&credentials%5Busername%5D=mneorr&credentials%5Bpassword%5D=123456xx%21%40crazy"
324
- @query.instance_variable_get(:@url).description.should.equal processed_url
325
- end
326
-
327
- it "should pass the new request in the new connection" do
328
- @query.connection.request.URL.description.should.equal @query.request.URL.description
329
- end
330
-
331
- it "should start the connection" do
332
- @query.connection.was_started.should.equal true
333
- end
334
-
335
- if App.ios?
336
- it "should turn on the network indicator" do
337
- UIApplication.sharedApplication.isNetworkActivityIndicatorVisible.should.equal true
338
- end
339
- end
340
- end
341
-
342
- describe "create request" do
343
-
344
- before do
345
- @url_string = 'http://initiated-request.dev/to convert'
346
- @headers = { fake: 'headers' }
347
- @get_query = BubbleWrap::HTTP::Query.new( @url_string , :get, { headers: @headers } )
348
- end
349
-
350
- it "should create a new request with HTTP method & header fields" do
351
- @query.request.HTTPMethod.should.equal @query.method
352
- @get_query.request.allHTTPHeaderFields.should.equal @headers
353
- end
354
-
355
- it "creates a new NSURLConnection and sets itself as a delegate" do
356
- @query.connection.delegate.should.equal @query
357
- end
358
-
359
- it "should patch the NSURLRequest with done_loading and done_loading!" do
360
- @query.request.done_loading?.should.equal @query.request.instance_variable_get(:@done_loading)
361
-
362
- @query.request.instance_variable_set(:@done_loading, false)
363
- @query.request.done_loading?.should.equal false
364
- @query.request.done_loading!
365
- @query.request.done_loading?.should.equal true
366
- end
367
-
368
- it "should pass the right arguments when creating new request" do
369
- @query.request.cachePolicy.should.equal @query.instance_variable_get(:@cache_policy)
370
- @query.request.timeoutInterval.should.equal @query.instance_variable_get(:@timeout)
371
- end
372
-
373
- end
374
-
375
- describe "create POST request" do
376
-
377
- before do
378
- @url_string = 'http://initiated-request.dev/post'
379
- @headers = { fake: 'headers' }
380
- @payload = { key:'abc1234' }
381
- @post_query = BubbleWrap::HTTP::Query.new(@url_string, :post, {headers: @headers, payload: @payload})
382
- end
383
-
384
- it "should add default Content Type if no payload is given" do
385
- query_without_payload = BubbleWrap::HTTP::Query.new(@url_string, :post, {headers: @headers})
386
- query_without_payload.request.allHTTPHeaderFields.should.include? 'Content-Type'
387
- end
388
-
389
- it "should automatically provide Content-Type if a payload is provided" do
390
- @post_query.request.allHTTPHeaderFields.should.include?('Content-Type')
391
- end
392
-
393
- it "should use the format parameter to decide the Content-Type" do
394
- json_query = BubbleWrap::HTTP::Query.new(@url_string, :post, {headers: @headers, format: :json, payload: "{\"key\":\"abc1234\"}"})
395
- json_query.request.allHTTPHeaderFields['Content-Type'].should.equal "application/json"
396
- end
397
-
398
- it "should default to multipart/form-data for payloads with a hash" do
399
- uuid = @post_query.instance_variable_get(:@boundary)
400
- @post_query.request.allHTTPHeaderFields['Content-Type'].should.equal "multipart/form-data; boundary=#{uuid}"
401
- end
402
-
403
- it "should default to application/x-www-form-urlencoded for non-hash payloads" do
404
- string_query = BubbleWrap::HTTP::Query.new(@url_string, :post, {headers: @headers, payload: "{\"key\":\"abc1234\"}"})
405
- string_query.request.allHTTPHeaderFields['Content-Type'].should.equal "application/x-www-form-urlencoded"
406
- end
407
-
408
- it "should not add Content-Type if you provide one yourself" do
409
- # also ensures check is case insenstive
410
- @headers = { fake: 'headers', 'CONTENT-TYPE' => 'x-banana' }
411
- @post_query = BubbleWrap::HTTP::Query.new(@url_string, :post, {headers: @headers, payload: @payload})
412
- @post_query.request.allHTTPHeaderFields['CONTENT-TYPE'].should.equal @headers['CONTENT-TYPE']
413
- end
414
-
415
- end
416
-
417
- describe "Generating payloads" do
418
-
419
- it "should create payload key/value pairs from nested hashes with prefix[key]=value" do
420
- expected_params = [
421
- ['user[name]', 'marin'],
422
- ['user[surname]', 'usalj'],
423
- ['twitter', '@mneorr'],
424
- ['website', 'mneorr.com'],
425
- ['values[]', 'apple'],
426
- ['values[]', 'orange'],
427
- ['values[]', 'peach'],
428
- ['credentials[username]', 'mneorr'],
429
- ['credentials[password]', '123456xx!@crazy']
430
- ]
431
- @query.send(:process_payload_hash, @payload).should.equal expected_params
432
- end
433
-
434
- it "should create payload key/value pairs from nested arrays of hashes with prefix[key][][nested_key]=value" do
435
- payload = {
436
- user: {
437
- phones_attributes: [
438
- { number: 1234567, area_code: 213 },
439
- { number: 7654321, area_code: 310 }
440
- ]
441
- }
442
- }
443
- expected_params = [
444
- ['user[phones_attributes][][number]', 1234567],
445
- ['user[phones_attributes][][area_code]', 213],
446
- ['user[phones_attributes][][number]', 7654321],
447
- ['user[phones_attributes][][area_code]', 310]
448
- ]
449
- @query.send(:process_payload_hash, payload).should.equal expected_params
450
- end
451
- end
452
-
453
- describe "when didReceiveResponse:" do
454
-
455
- it "should assign status_code, headers and response_size" do
456
- headers = { foo: 'bar' }
457
- status_code = 234
458
- length = 123.53
459
-
460
- response = FakeURLResponse.new(status_code, headers, length)
461
- @query.connection(nil, didReceiveResponse:response)
462
-
463
- @query.status_code.should.equal status_code
464
- @query.response_headers.should.equal headers
465
- @query.response_size.should.equal length
466
- end
467
-
468
- end
469
-
470
- describe "when didRecieveData:" do
471
-
472
- def query_received_data
473
- @query.instance_variable_get(:@received_data)
474
- end
475
-
476
- it "should initialize @received_data and append the received data" do
477
- query_received_data.should.equal nil
478
- data = NSData.dataWithBytes(Pointer.new(:char, 'abc'), length:24)
479
-
480
- @query.connection(nil, didReceiveData:nil)
481
- query_received_data.should.not.equal nil
482
-
483
- @query.connection(nil, didReceiveData:data)
484
- query_received_data.length.should.equal 24
485
-
486
- @query.connection(nil, didReceiveData:data)
487
- query_received_data.length.should.equal 48
488
- end
489
-
490
- end
491
-
492
-
493
-
494
- describe "when requestDidFailWithError:" do
495
- before do
496
- @fake_error = NSError.errorWithDomain('testing', code:7768, userInfo:nil)
497
- end
498
-
499
- if App.ios?
500
- it "should turn off network indicator" do
501
- UIApplication.sharedApplication.isNetworkActivityIndicatorVisible.should == true
502
- @query.connection(nil, didFailWithError:@fake_error)
503
- UIApplication.sharedApplication.isNetworkActivityIndicatorVisible.should == false
504
- end
505
- end
506
-
507
- it "should set request_done to true" do
508
- @query.request.done_loading?.should == false
509
- @query.connection(nil, didFailWithError:@fake_error)
510
- @query.request.done_loading?.should == true
511
- end
512
-
513
- it "should set the error message to response object" do
514
- @query.response.error_message.should.equal nil
515
- @query.connection(nil, didFailWithError:@fake_error)
516
- @query.response.error_message.should.equal @fake_error.localizedDescription
517
- end
518
-
519
- it "should set the error object to response object" do
520
- @query.response.error.should.equal nil
521
- @query.connection(nil, didFailWithError:@fake_error)
522
- @query.response.error.code.should.equal @fake_error.code
523
- end
524
-
525
- it "should check if there's a callback block and pass the response in" do
526
- expected_response = BubbleWrap::HTTP::Response.new
527
- real_response = nil
528
- block = lambda{ |response, query| real_response = response }
529
-
530
- query = BubbleWrap::HTTP::Query.new(@localhost_url, :get, { :action => block })
531
- query.instance_variable_set(:@response, expected_response)
532
-
533
- query.connection(nil, didFailWithError:@fake_error)
534
- real_response.should.equal expected_response
535
- end
536
-
537
- end
538
-
539
- describe "when connectionDidFinishLoading:" do
540
-
541
- if App.ios?
542
- it "should turn off the network indicator" do
543
- UIApplication.sharedApplication.isNetworkActivityIndicatorVisible.should == true
544
-
545
- @query.connectionDidFinishLoading(nil)
546
- UIApplication.sharedApplication.isNetworkActivityIndicatorVisible.should == false
547
- end
548
- end
549
-
550
- it "should set request_done to true" do
551
- @query.request.done_loading?.should == false
552
-
553
- @query.connectionDidFinishLoading(nil)
554
- @query.request.done_loading?.should == true
555
- end
556
-
557
- it "should set response_body to @received data if not nil" do
558
- data = NSData.dataWithBytes(Pointer.new(:char, 'abc'), length:24)
559
- headers = { foo: 'bar' }
560
- status_code = 234
561
- response = FakeURLResponse.new(status_code, headers, 65456)
562
-
563
- @query.connection(nil, didReceiveResponse:response)
564
- @query.connection(nil, didReceiveData:data)
565
- @query.connectionDidFinishLoading(nil)
566
-
567
- @query.response.body.should.equal data
568
- @query.response.status_code.should.equal status_code
569
- @query.response.headers.should.equal headers
570
- @query.response.url.should.equal @query.instance_variable_get(:@url)
571
- end
572
-
573
- it "should check if there's a callback block and pass the response in" do
574
- expected_response = BubbleWrap::HTTP::Response.new
575
- real_response = nil
576
- block = lambda{ |response, query| real_response = response }
577
- query = BubbleWrap::HTTP::Query.new(@localhost_url, :get, { :action => block })
578
- query.instance_variable_set(:@response, expected_response)
579
-
580
- query.connectionDidFinishLoading(nil)
581
- real_response.should.equal expected_response
582
- end
583
-
584
- end
585
-
586
- describe "when connection:willSendRequest:redirectResponse:" do
587
- before do
588
- @request = NSMutableURLRequest.requestWithURL NSURL.URLWithString('http://fakehost.local/')
589
- end
590
-
591
- it "should forward the new request for 30 times/redirections" do
592
- 1.upto(35) do |numbah|
593
- request = @query.connection(nil, willSendRequest:@request, redirectResponse:nil)
594
- request.should.equal numbah < 30 ? @request : nil
595
- end
596
- end
597
-
598
- it "should always allow canonical redirects" do
599
- @query.options.update({:no_redirect => 1})
600
- request = @query.connection(nil, willSendRequest:@request, redirectResponse:nil)
601
- request.should.equal @request
602
- end
603
-
604
- it "should disallow non-canonical redirects if requested not to" do
605
- @query.options.update({:no_redirect => 1})
606
- request = @query.connection(nil, willSendRequest:@request, redirectResponse:"monkey")
607
- request.should.equal nil
608
- end
609
-
610
- it "should allow non-canonical redirects by default" do
611
- @query.options.delete(:no_redirect)
612
- request = @query.connection(nil, willSendRequest:@request, redirectResponse:"monkey")
613
- request.should.equal @request
614
- end
615
-
616
- describe "after 30 redirects" do
617
- before do
618
- 31.times do
619
- @query.connection(nil, willSendRequest:@request, redirectResponse:nil)
620
- end
621
- end
622
-
623
- it "sets the error message/code on response" do
624
- @real_response.error_message.should.equal "Too many redirections"
625
- @real_response.error.code.should.equal NSURLErrorHTTPTooManyRedirects
626
- end
627
-
628
- it "sets the request.done_loading" do
629
- @query.request.done_loading?.should.equal true
630
- end
631
-
632
- it "calls the delegator block" do
633
- @delegator_was_called.should.equal true
634
- end
635
- end
636
-
637
- it "should update the request URL after redirecting by default" do
638
- query = BubbleWrap::HTTP::Query.new( @localhost_url , :get, {} )
639
- redirected_request = NSMutableURLRequest.requestWithURL NSURL.URLWithString('http://expanded.local/')
640
- query.connection(nil, willSendRequest:redirected_request, redirectResponse:nil)
641
- query.connectionDidFinishLoading(nil)
642
- query.response.url.absoluteString.should.equal redirected_request.URL.absoluteString
643
- query.response.original_url.absoluteString.should.equal @localhost_url
644
- end
645
-
646
- end
647
-
648
- describe "didReceiveAuthenticationChallenge" do
649
- before do
650
- @challenge = FakeChallenge.new
651
- @challenge.previousFailureCount = 0
652
- @query.connection(nil, didReceiveAuthenticationChallenge:@challenge)
653
- end
654
-
655
- describe "given the failure count was not 0" do
656
- before { @challenge.previousFailureCount = 1 }
657
-
658
- it "should cancel the authentication" do
659
- @query.connection(nil, didReceiveAuthenticationChallenge:@challenge)
660
- @challenge.sender.was_cancelled.should.equal true
661
- end
662
-
663
- it "should set the response fields" do
664
- @query.connection(nil, didReceiveAuthenticationChallenge:@challenge)
665
- @query.response.status_code.should.equal @challenge.failureResponse.statusCode
666
- end
667
- end
668
-
669
- it "should pass in Credentials and the challenge itself to the sender" do
670
- @challenge.sender.challenge.should.equal @challenge
671
- @challenge.sender.credential.user.should.equal @credentials[:username]
672
- @challenge.sender.credential.password.should.equal @credentials[:password]
673
- end
674
-
675
- it "should use Credential Persistence set in options" do
676
- @challenge.sender.credential.persistence.should.equal @credential_persistence
677
- end
678
-
679
- it 'should continue without credentials when no credentials provided' do
680
- @options.delete :credentials
681
- query = BubbleWrap::HTTP::Query.new( @localhost_url , :get, @options )
682
- query.connection(nil, didReceiveAuthenticationChallenge:@challenge)
683
- @challenge.sender.continue_without_credential.should.equal true
684
- end
685
-
686
- end
687
-
688
- describe 'cancel' do
689
- before do
690
- @doa_query = BubbleWrap::HTTP::Query.new(@localhost_url, :get)
691
- @doa_query.cancel
692
- end
693
-
694
- it "should cancel the connection" do
695
- @doa_query.connection.was_cancelled.should.equal true
696
- end
697
-
698
- if App.ios?
699
- it "should turn off the network indicator" do
700
- UIApplication.sharedApplication.isNetworkActivityIndicatorVisible.should.equal false
701
- end
702
- end
703
- end
704
-
705
- describe "empty payload" do
706
-
707
- before do
708
- @payload = {}
709
- @url_string = 'http://fake.url/method'
710
- @get_query = BubbleWrap::HTTP::Query.new(@url_string, :get, :payload => @payload)
711
- end
712
-
713
- it "should not append a ? to the end of the URL" do
714
- @get_query.instance_variable_get(:@url).description.should.equal('http://fake.url/method')
715
- end
716
-
717
- end
718
-
719
- describe "properly format payload to url get query string" do
720
-
721
- before do
722
- @payload = {"we love" => '#==Rock&Roll==#', "radio" => "Ga Ga", "qual" => 3.0, "incr" => -1, "RFC3986" => "!*'();:@&=+$,/?%#[]"}
723
- @url_string = 'http://fake.url/method'
724
- @get_query = BubbleWrap::HTTP::Query.new(@url_string, :get, :payload => @payload)
725
- @escaped_url = "http://fake.url/method?we%20love=%23%3D%3DRock%26Roll%3D%3D%23&radio=Ga%20Ga&qual=3.0&incr=-1&RFC3986=%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%25%23%5B%5D"
726
- end
727
-
728
- it "should escape !*'();:@&=+$,/?%#[] characters only in keys and values" do
729
- @get_query.instance_variable_get(:@url).description.should.equal @escaped_url
730
- end
731
-
732
- end
733
-
734
- describe 'properly support cookie-option for nsmutableurlrequest' do
735
-
736
- before do
737
- @no_cookie_query = BubbleWrap::HTTP::Query.new("http://haz-no-cookiez.url", :get, {:payload => {:something => "else"}, :cookies => false})
738
- @cookie_query = BubbleWrap::HTTP::Query.new("http://haz-cookiez.url", :get, :payload => {:something => "else"})
739
- end
740
-
741
- it 'should disabled cookie-usage on nsurlrequest' do
742
- @no_cookie_query.instance_variable_get(:@request).HTTPShouldHandleCookies.should.equal false
743
- end
744
-
745
- it 'should keep sane cookie-related defaults on nsurlrequest' do
746
- @cookie_query.instance_variable_get(:@request).HTTPShouldHandleCookies.should.equal true
747
- end
748
-
749
-
750
- end
751
-
752
- class FakeSender
753
- attr_reader :challenge, :credential, :was_cancelled, :continue_without_credential
754
- def cancelAuthenticationChallenge(challenge)
755
- @was_cancelled = true
756
- end
757
- def useCredential(credential, forAuthenticationChallenge:challenge)
758
- @challenge = challenge
759
- @credential = credential
760
- end
761
- def continueWithoutCredentialForAuthenticationChallenge(challenge)
762
- @continue_without_credential = true
763
- end
764
- end
765
-
766
- class FakeChallenge
767
- attr_accessor :previousFailureCount, :failureResponse
768
-
769
- def sender
770
- @fake_sender ||= FakeSender.new
771
- end
772
-
773
- def failureResponse
774
- @failureResponse ||= FakeURLResponse.new(401, { bla: "123" }, 123)
775
- end
776
- end
777
-
778
- class BubbleWrap::HTTP::Query
779
- def create_connection(request, delegate); FakeURLConnection.new(request, delegate); end
780
- end
781
-
782
- class FakeURLConnection < NSURLConnection
783
- attr_reader :delegate, :request, :was_started, :was_cancelled
784
- def initialize(request, delegate)
785
- @request = request
786
- @delegate = delegate
787
- self.class.connectionWithRequest(request, delegate:delegate)
788
- end
789
- def start
790
- @was_started = true
791
- @was_cancelled = false
792
- super
793
- end
794
- def cancel
795
- @was_cancelled = true
796
- end
797
- end
798
-
799
- class FakeURLResponse < NSHTTPURLResponse
800
- attr_reader :statusCode, :allHeaderFields, :expectedContentLength
801
- def initialize(status_code, headers, length)
802
- @statusCode = status_code
803
- @allHeaderFields = headers
804
- @expectedContentLength = length
805
- end
806
- end
807
-
808
- end