pusher 1.3.2 → 2.0.3

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.
data/spec/client_spec.rb DELETED
@@ -1,668 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'em-http'
4
-
5
- describe Pusher do
6
- # The behaviour should be the same when using the Client object, or the
7
- # 'global' client delegated through the Pusher class
8
- [lambda { Pusher }, lambda { Pusher::Client.new }].each do |client_gen|
9
- before :each do
10
- @client = client_gen.call
11
- end
12
-
13
- describe 'default configuration' do
14
- it 'should be preconfigured for api host' do
15
- expect(@client.host).to eq('api.pusherapp.com')
16
- end
17
-
18
- it 'should be preconfigured for port 80' do
19
- expect(@client.port).to eq(80)
20
- end
21
-
22
- it 'should use standard logger if no other logger if defined' do
23
- Pusher.logger.debug('foo')
24
- expect(Pusher.logger).to be_kind_of(Logger)
25
- end
26
- end
27
-
28
- describe 'logging configuration' do
29
- it "can be configured to use any logger" do
30
- logger = double("ALogger")
31
- expect(logger).to receive(:debug).with('foo')
32
- Pusher.logger = logger
33
- Pusher.logger.debug('foo')
34
- Pusher.logger = nil
35
- end
36
- end
37
-
38
- describe "configuration using url" do
39
- it "should be possible to configure everything by setting the url" do
40
- @client.url = "test://somekey:somesecret@api.staging.pusherapp.com:8080/apps/87"
41
-
42
- expect(@client.scheme).to eq('test')
43
- expect(@client.host).to eq('api.staging.pusherapp.com')
44
- expect(@client.port).to eq(8080)
45
- expect(@client.key).to eq('somekey')
46
- expect(@client.secret).to eq('somesecret')
47
- expect(@client.app_id).to eq('87')
48
- end
49
-
50
- it "should override scheme and port when setting encrypted=true after url" do
51
- @client.url = "http://somekey:somesecret@api.staging.pusherapp.com:8080/apps/87"
52
- @client.encrypted = true
53
-
54
- expect(@client.scheme).to eq('https')
55
- expect(@client.port).to eq(443)
56
- end
57
-
58
- it "should fail on bad urls" do
59
- expect { @client.url = "gopher/somekey:somesecret@://api.staging.pusherapp.co://m:8080\apps\87" }.to raise_error(URI::InvalidURIError)
60
- end
61
-
62
- it "should raise exception if app_id is not configured" do
63
- @client.app_id = nil
64
- expect {
65
- @client.url
66
- }.to raise_error(Pusher::ConfigurationError)
67
- end
68
-
69
- end
70
-
71
- describe 'configuring the cluster' do
72
- it 'should set a new default host' do
73
- @client.cluster = 'eu'
74
- expect(@client.host).to eq('api-eu.pusher.com')
75
- end
76
-
77
- it 'should be overridden by host if it comes after' do
78
- @client.cluster = 'eu'
79
- @client.host = 'api.staging.pusher.com'
80
- expect(@client.host).to eq('api.staging.pusher.com')
81
- end
82
-
83
- it 'should be overridden by url if it comes after' do
84
- @client.cluster = 'eu'
85
- @client.url = "http://somekey:somesecret@api.staging.pusherapp.com:8080/apps/87"
86
-
87
- expect(@client.host).to eq('api.staging.pusherapp.com')
88
- end
89
-
90
- it 'should override the url configuration if it comes after' do
91
- @client.url = "http://somekey:somesecret@api.staging.pusherapp.com:8080/apps/87"
92
- @client.cluster = 'eu'
93
- expect(@client.host).to eq('api-eu.pusher.com')
94
- end
95
-
96
- it 'should override the host configuration if it comes after' do
97
- @client.host = 'api.staging.pusher.com'
98
- @client.cluster = 'eu'
99
- expect(@client.host).to eq('api-eu.pusher.com')
100
- end
101
- end
102
-
103
- describe 'configuring TLS' do
104
- it 'should set port and scheme if "use_tls" enabled' do
105
- client = Pusher::Client.new({
106
- :use_tls => true,
107
- })
108
- expect(client.scheme).to eq('https')
109
- expect(client.port).to eq(443)
110
- end
111
-
112
- it 'should set port and scheme if "encrypted" enabled' do
113
- client = Pusher::Client.new({
114
- :encrypted => true,
115
- })
116
- expect(client.scheme).to eq('https')
117
- expect(client.port).to eq(443)
118
- end
119
-
120
- it 'should use non-TLS port and scheme if "encrypted" or "use_tls" are not set' do
121
- client = Pusher::Client.new
122
- expect(client.scheme).to eq('http')
123
- expect(client.port).to eq(80)
124
- end
125
-
126
- it 'should override port if "use_tls" option set but a different port is specified' do
127
- client = Pusher::Client.new({
128
- :use_tls => true,
129
- :port => 8443
130
- })
131
- expect(client.scheme).to eq('https')
132
- expect(client.port).to eq(8443)
133
- end
134
-
135
- end
136
-
137
- describe 'configuring a http proxy' do
138
- it "should be possible to configure everything by setting the http_proxy" do
139
- @client.http_proxy = 'http://someuser:somepassword@proxy.host.com:8080'
140
-
141
- expect(@client.proxy).to eq({:scheme => 'http', :host => 'proxy.host.com', :port => 8080, :user => 'someuser', :password => 'somepassword'})
142
- end
143
- end
144
-
145
- describe 'configuring from env' do
146
- after do
147
- ENV['PUSHER_URL'] = nil
148
- end
149
-
150
- it "works" do
151
- url = "http://somekey:somesecret@api.staging.pusherapp.com:8080/apps/87"
152
- ENV['PUSHER_URL'] = url
153
-
154
- client = Pusher::Client.from_env
155
- expect(client.key).to eq("somekey")
156
- expect(client.secret).to eq("somesecret")
157
- expect(client.app_id).to eq("87")
158
- expect(client.url.to_s).to eq("http://api.staging.pusherapp.com:8080/apps/87")
159
- end
160
- end
161
-
162
- describe 'configuring from url' do
163
- it "works" do
164
- url = "http://somekey:somesecret@api.staging.pusherapp.com:8080/apps/87"
165
-
166
- client = Pusher::Client.from_url(url)
167
- expect(client.key).to eq("somekey")
168
- expect(client.secret).to eq("somesecret")
169
- expect(client.app_id).to eq("87")
170
- expect(client.url.to_s).to eq("http://api.staging.pusherapp.com:8080/apps/87")
171
- end
172
- end
173
-
174
- describe 'when configured' do
175
- before :each do
176
- @client.app_id = '20'
177
- @client.key = '12345678900000001'
178
- @client.secret = '12345678900000001'
179
- end
180
-
181
- describe '#[]' do
182
- before do
183
- @channel = @client['test_channel']
184
- end
185
-
186
- it 'should return a channel' do
187
- expect(@channel).to be_kind_of(Pusher::Channel)
188
- end
189
-
190
- it "should raise exception if app_id is not configured" do
191
- @client.app_id = nil
192
- expect {
193
- @channel.trigger!('foo', 'bar')
194
- }.to raise_error(Pusher::ConfigurationError)
195
- end
196
- end
197
-
198
- describe '#channels' do
199
- it "should call the correct URL and symbolise response correctly" do
200
- api_path = %r{/apps/20/channels}
201
- stub_request(:get, api_path).to_return({
202
- :status => 200,
203
- :body => MultiJson.encode('channels' => {
204
- "channel1" => {},
205
- "channel2" => {}
206
- })
207
- })
208
- expect(@client.channels).to eq({
209
- :channels => {
210
- "channel1" => {},
211
- "channel2" => {}
212
- }
213
- })
214
- end
215
- end
216
-
217
- describe '#channel_info' do
218
- it "should call correct URL and symbolise response" do
219
- api_path = %r{/apps/20/channels/mychannel}
220
- stub_request(:get, api_path).to_return({
221
- :status => 200,
222
- :body => MultiJson.encode({
223
- 'occupied' => false,
224
- })
225
- })
226
- expect(@client.channel_info('mychannel')).to eq({
227
- :occupied => false,
228
- })
229
- end
230
- end
231
-
232
- describe '#channel_users' do
233
- it "should call correct URL and symbolise response" do
234
- api_path = %r{/apps/20/channels/mychannel/users}
235
- stub_request(:get, api_path).to_return({
236
- :status => 200,
237
- :body => MultiJson.encode({
238
- 'users' => [{ 'id' => 1 }]
239
- })
240
- })
241
- expect(@client.channel_users('mychannel')).to eq({
242
- :users => [{ 'id' => 1}]
243
- })
244
- end
245
- end
246
-
247
- describe '#authenticate' do
248
- before :each do
249
- @custom_data = {:uid => 123, :info => {:name => 'Foo'}}
250
- end
251
-
252
- it 'should return a hash with signature including custom data and data as json string' do
253
- allow(MultiJson).to receive(:encode).with(@custom_data).and_return 'a json string'
254
-
255
- response = @client.authenticate('test_channel', '1.1', @custom_data)
256
-
257
- expect(response).to eq({
258
- :auth => "12345678900000001:#{hmac(@client.secret, "1.1:test_channel:a json string")}",
259
- :channel_data => 'a json string'
260
- })
261
- end
262
-
263
- end
264
-
265
- describe '#trigger' do
266
- before :each do
267
- @api_path = %r{/apps/20/events}
268
- stub_request(:post, @api_path).to_return({
269
- :status => 200,
270
- :body => MultiJson.encode({})
271
- })
272
- end
273
-
274
- it "should call correct URL" do
275
- expect(@client.trigger(['mychannel'], 'event', {'some' => 'data'})).
276
- to eq({})
277
- end
278
-
279
- it "should not allow too many channels" do
280
- expect {
281
- @client.trigger((0..11).map{|i| 'mychannel#{i}'},
282
- 'event', {'some' => 'data'}, {
283
- :socket_id => "12.34"
284
- })}.to raise_error(Pusher::Error)
285
- end
286
-
287
- it "should pass any parameters in the body of the request" do
288
- @client.trigger(['mychannel', 'c2'], 'event', {'some' => 'data'}, {
289
- :socket_id => "12.34"
290
- })
291
- expect(WebMock).to have_requested(:post, @api_path).with { |req|
292
- parsed = MultiJson.decode(req.body)
293
- expect(parsed["name"]).to eq('event')
294
- expect(parsed["channels"]).to eq(["mychannel", "c2"])
295
- expect(parsed["socket_id"]).to eq('12.34')
296
- }
297
- end
298
-
299
- it "should convert non string data to JSON before posting" do
300
- @client.trigger(['mychannel'], 'event', {'some' => 'data'})
301
- expect(WebMock).to have_requested(:post, @api_path).with { |req|
302
- expect(MultiJson.decode(req.body)["data"]).to eq('{"some":"data"}')
303
- }
304
- end
305
-
306
- it "should accept a single channel as well as an array" do
307
- @client.trigger('mychannel', 'event', {'some' => 'data'})
308
- expect(WebMock).to have_requested(:post, @api_path).with { |req|
309
- expect(MultiJson.decode(req.body)["channels"]).to eq(['mychannel'])
310
- }
311
- end
312
-
313
- %w[app_id key secret].each do |key|
314
- it "should fail in missing #{key}" do
315
- @client.public_send("#{key}=", nil)
316
- expect {
317
- @client.trigger('mychannel', 'event', {'some' => 'data'})
318
- }.to raise_error(Pusher::ConfigurationError)
319
- expect(WebMock).not_to have_requested(:post, @api_path).with { |req|
320
- expect(MultiJson.decode(req.body)["channels"]).to eq(['mychannel'])
321
- }
322
- end
323
- end
324
- end
325
-
326
- describe '#trigger_batch' do
327
- before :each do
328
- @api_path = %r{/apps/20/batch_events}
329
- stub_request(:post, @api_path).to_return({
330
- :status => 200,
331
- :body => MultiJson.encode({})
332
- })
333
- end
334
-
335
- it "should call correct URL" do
336
- expect(@client.trigger_batch(channel: 'mychannel', name: 'event', data: {'some' => 'data'})).
337
- to eq({})
338
- end
339
-
340
- it "should convert non string data to JSON before posting" do
341
- @client.trigger_batch(
342
- {channel: 'mychannel', name: 'event', data: {'some' => 'data'}},
343
- {channel: 'mychannel', name: 'event', data: 'already encoded'},
344
- )
345
- expect(WebMock).to have_requested(:post, @api_path).with { |req|
346
- parsed = MultiJson.decode(req.body)
347
- expect(parsed).to eq(
348
- "batch" => [
349
- { "channel" => "mychannel", "name" => "event", "data" => "{\"some\":\"data\"}"},
350
- { "channel" => "mychannel", "name" => "event", "data" => "already encoded"}
351
- ]
352
- )
353
- }
354
- end
355
- end
356
-
357
- describe '#trigger_async' do
358
- before :each do
359
- @api_path = %r{/apps/20/events}
360
- stub_request(:post, @api_path).to_return({
361
- :status => 200,
362
- :body => MultiJson.encode({})
363
- })
364
- end
365
-
366
- it "should call correct URL" do
367
- EM.run {
368
- @client.trigger_async('mychannel', 'event', {'some' => 'data'}).callback { |r|
369
- expect(r).to eq({})
370
- EM.stop
371
- }
372
- }
373
- end
374
-
375
- it "should pass any parameters in the body of the request" do
376
- EM.run {
377
- @client.trigger_async('mychannel', 'event', {'some' => 'data'}, {
378
- :socket_id => "12.34"
379
- }).callback {
380
- expect(WebMock).to have_requested(:post, @api_path).with { |req|
381
- expect(MultiJson.decode(req.body)["socket_id"]).to eq('12.34')
382
- }
383
- EM.stop
384
- }
385
- }
386
- end
387
-
388
- it "should convert non string data to JSON before posting" do
389
- EM.run {
390
- @client.trigger_async('mychannel', 'event', {'some' => 'data'}).callback {
391
- expect(WebMock).to have_requested(:post, @api_path).with { |req|
392
- expect(MultiJson.decode(req.body)["data"]).to eq('{"some":"data"}')
393
- }
394
- EM.stop
395
- }
396
- }
397
- end
398
- end
399
-
400
- [:get, :post].each do |verb|
401
- describe "##{verb}" do
402
- before :each do
403
- @url_regexp = %r{api.pusherapp.com}
404
- stub_request(verb, @url_regexp).
405
- to_return(:status => 200, :body => "{}")
406
- end
407
-
408
- let(:call_api) { @client.send(verb, '/path') }
409
-
410
- it "should use http by default" do
411
- call_api
412
- expect(WebMock).to have_requested(verb, %r{http://api.pusherapp.com/apps/20/path})
413
- end
414
-
415
- it "should use https if configured" do
416
- @client.encrypted = true
417
- call_api
418
- expect(WebMock).to have_requested(verb, %r{https://api.pusherapp.com})
419
- end
420
-
421
- it "should format the respose hash with symbols at first level" do
422
- stub_request(verb, @url_regexp).to_return({
423
- :status => 200,
424
- :body => MultiJson.encode({'something' => {'a' => 'hash'}})
425
- })
426
- expect(call_api).to eq({
427
- :something => {'a' => 'hash'}
428
- })
429
- end
430
-
431
- it "should catch all http exceptions and raise a Pusher::HTTPError wrapping the original error" do
432
- stub_request(verb, @url_regexp).to_raise(HTTPClient::TimeoutError)
433
-
434
- error = nil
435
- begin
436
- call_api
437
- rescue => e
438
- error = e
439
- end
440
-
441
- expect(error.class).to eq(Pusher::HTTPError)
442
- expect(error).to be_kind_of(Pusher::Error)
443
- expect(error.message).to eq('Exception from WebMock (HTTPClient::TimeoutError)')
444
- expect(error.original_error.class).to eq(HTTPClient::TimeoutError)
445
- end
446
-
447
- it "should raise Pusher::Error if call returns 400" do
448
- stub_request(verb, @url_regexp).to_return({:status => 400})
449
- expect { call_api }.to raise_error(Pusher::Error)
450
- end
451
-
452
- it "should raise AuthenticationError if pusher returns 401" do
453
- stub_request(verb, @url_regexp).to_return({:status => 401})
454
- expect { call_api }.to raise_error(Pusher::AuthenticationError)
455
- end
456
-
457
- it "should raise Pusher::Error if pusher returns 404" do
458
- stub_request(verb, @url_regexp).to_return({:status => 404})
459
- expect { call_api }.to raise_error(Pusher::Error, '404 Not found (/apps/20/path)')
460
- end
461
-
462
- it "should raise Pusher::Error if pusher returns 407" do
463
- stub_request(verb, @url_regexp).to_return({:status => 407})
464
- expect { call_api }.to raise_error(Pusher::Error, 'Proxy Authentication Required')
465
- end
466
-
467
- it "should raise Pusher::Error if pusher returns 413" do
468
- stub_request(verb, @url_regexp).to_return({:status => 413})
469
- expect { call_api }.to raise_error(Pusher::Error, 'Payload Too Large > 10KB')
470
- end
471
-
472
- it "should raise Pusher::Error if pusher returns 500" do
473
- stub_request(verb, @url_regexp).to_return({:status => 500, :body => "some error"})
474
- expect { call_api }.to raise_error(Pusher::Error, 'Unknown error (status code 500): some error')
475
- end
476
- end
477
- end
478
-
479
- describe "async calling without eventmachine" do
480
- [[:get, :get_async], [:post, :post_async]].each do |verb, method|
481
- describe "##{method}" do
482
- before :each do
483
- @url_regexp = %r{api.pusherapp.com}
484
- stub_request(verb, @url_regexp).
485
- to_return(:status => 200, :body => "{}")
486
- end
487
-
488
- let(:call_api) {
489
- @client.send(method, '/path').tap { |c|
490
- # Allow the async thread (inside httpclient) to run
491
- while !c.finished?
492
- sleep 0.01
493
- end
494
- }
495
- }
496
-
497
- it "should use http by default" do
498
- call_api
499
- expect(WebMock).to have_requested(verb, %r{http://api.pusherapp.com/apps/20/path})
500
- end
501
-
502
- it "should use https if configured" do
503
- @client.encrypted = true
504
- call_api
505
- expect(WebMock).to have_requested(verb, %r{https://api.pusherapp.com})
506
- end
507
-
508
- # Note that the raw httpclient connection object is returned and
509
- # the response isn't handled (by handle_response) in the normal way.
510
- it "should return a httpclient connection object" do
511
- connection = call_api
512
- expect(connection.finished?).to be_truthy
513
- response = connection.pop
514
- expect(response.status).to eq(200)
515
- expect(response.body.read).to eq("{}")
516
- end
517
- end
518
- end
519
- end
520
-
521
- describe "async calling with eventmachine" do
522
- [[:get, :get_async], [:post, :post_async]].each do |verb, method|
523
- describe "##{method}" do
524
- before :each do
525
- @url_regexp = %r{api.pusherapp.com}
526
- stub_request(verb, @url_regexp).
527
- to_return(:status => 200, :body => "{}")
528
- end
529
-
530
- let(:call_api) { @client.send(method, '/path') }
531
-
532
- it "should use http by default" do
533
- EM.run {
534
- call_api.callback {
535
- expect(WebMock).to have_requested(verb, %r{http://api.pusherapp.com/apps/20/path})
536
- EM.stop
537
- }
538
- }
539
- end
540
-
541
- it "should use https if configured" do
542
- EM.run {
543
- @client.encrypted = true
544
- call_api.callback {
545
- expect(WebMock).to have_requested(verb, %r{https://api.pusherapp.com})
546
- EM.stop
547
- }
548
- }
549
- end
550
-
551
- it "should format the respose hash with symbols at first level" do
552
- EM.run {
553
- stub_request(verb, @url_regexp).to_return({
554
- :status => 200,
555
- :body => MultiJson.encode({'something' => {'a' => 'hash'}})
556
- })
557
- call_api.callback { |response|
558
- expect(response).to eq({
559
- :something => {'a' => 'hash'}
560
- })
561
- EM.stop
562
- }
563
- }
564
- end
565
-
566
- it "should errback with Pusher::Error on unsuccessful response" do
567
- EM.run {
568
- stub_request(verb, @url_regexp).to_return({:status => 400})
569
-
570
- call_api.errback { |e|
571
- expect(e.class).to eq(Pusher::Error)
572
- EM.stop
573
- }.callback {
574
- fail
575
- }
576
- }
577
- end
578
- end
579
- end
580
- end
581
- end
582
-
583
- describe "native notifications" do
584
- before :each do
585
- @client.app_id = "20"
586
- @client.key = "testytest"
587
- @client.secret = "mysupersecretkey"
588
- end
589
-
590
- it "should configure a native notification client using the pusher client object" do
591
- expect(@client.notification_client).to_not be(nil)
592
- end
593
-
594
- it "should use the default host if not provided" do
595
- expect(@client.notification_host).to eq("nativepush-cluster1.pusher.com")
596
- end
597
-
598
- it "should use a newly provided host" do
599
- @client.notification_host = "test.com"
600
- expect(@client.notification_host).to eq("test.com")
601
- end
602
-
603
- it "should set the native notification client host to the same one" do
604
- expect(@client.notification_host).to eq(@client.notification_client.host)
605
- end
606
-
607
- it "should raise an error if no interest is provided" do
608
- payload = {
609
- gcm: {
610
- notification: {
611
- title: "Hello",
612
- icon: "icon",
613
- }
614
- }
615
- }
616
-
617
- expect { @client.notify([], payload) }.to raise_error(Pusher::Error)
618
- end
619
-
620
- it "should send a request to the notifications endpoint" do
621
- notification_host_regexp = %r{nativepush-cluster1.pusher.com}
622
- payload = {
623
- interests: ["test"],
624
- gcm: {
625
- notification: {
626
- title: "Hello",
627
- icon: "icon",
628
- }
629
- }
630
- }
631
-
632
- stub_request(
633
- :post,
634
- notification_host_regexp,
635
- ).with(
636
- body: MultiJson.encode(payload)
637
- ).to_return({
638
- :status => 200,
639
- :body => MultiJson.encode({ :foo => "bar" })
640
- })
641
-
642
- res = @client.notify(["test"], payload)
643
- expect(res).to eq({foo: "bar"})
644
- end
645
- end
646
- end
647
-
648
- describe 'configuring cluster' do
649
- it 'should allow clients to specify the cluster only with the default host' do
650
- client = Pusher::Client.new({
651
- :scheme => 'http',
652
- :cluster => 'eu',
653
- :port => 80
654
- })
655
- expect(client.host).to eq('api-eu.pusher.com')
656
- end
657
-
658
- it 'should always have host override any supplied cluster value' do
659
- client = Pusher::Client.new({
660
- :scheme => 'http',
661
- :host => 'api.staging.pusherapp.com',
662
- :cluster => 'eu',
663
- :port => 80
664
- })
665
- expect(client.host).to eq('api.staging.pusherapp.com')
666
- end
667
- end
668
- end
data/spec/spec_helper.rb DELETED
@@ -1,26 +0,0 @@
1
- begin
2
- require 'bundler/setup'
3
- rescue LoadError
4
- puts 'although not required, it is recommended that you use bundler when running the tests'
5
- end
6
-
7
- ENV['PUSHER_URL']= 'http://some:secret@api.secret.pusherapp.com:441/apps/54'
8
-
9
- require 'rspec'
10
- require 'em-http' # As of webmock 1.4.0, em-http must be loaded first
11
- require 'webmock/rspec'
12
-
13
- require 'pusher'
14
- require 'eventmachine'
15
-
16
- RSpec.configure do |config|
17
- config.before(:each) do
18
- WebMock.reset!
19
- WebMock.disable_net_connect!
20
- end
21
- end
22
-
23
- def hmac(key, data)
24
- digest = OpenSSL::Digest::SHA256.new
25
- OpenSSL::HMAC.hexdigest(digest, key, data)
26
- end