bubble-wrap 1.5.0 → 1.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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