bubble-wrap 1.2.0 → 1.3.0.osx

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