ably-rest 0.8.9 → 0.8.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +54 -21
  3. data/ably-rest.gemspec +6 -2
  4. data/lib/ably-rest.rb +2 -0
  5. data/lib/submodules/ably-ruby/CHANGELOG.md +42 -4
  6. data/lib/submodules/ably-ruby/README.md +2 -3
  7. data/lib/submodules/ably-ruby/ably.gemspec +6 -2
  8. data/lib/submodules/ably-ruby/lib/ably/auth.rb +80 -21
  9. data/lib/submodules/ably-ruby/lib/ably/modules/message_emitter.rb +5 -2
  10. data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +22 -4
  11. data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +1 -1
  12. data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +8 -6
  13. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +1 -1
  14. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +4 -2
  15. data/lib/submodules/ably-ruby/lib/ably/version.rb +3 -1
  16. data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +189 -0
  17. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +19 -0
  18. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +20 -0
  19. data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +132 -10
  20. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +19 -0
  21. data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +122 -4
  22. data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +17 -0
  23. data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +3 -3
  24. data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +28 -0
  25. metadata +2 -2
@@ -1463,6 +1463,25 @@ describe Ably::Realtime::Presence, :event_machine do
1463
1463
  stop_reactor
1464
1464
  end
1465
1465
  end
1466
+
1467
+ context 'with a callback that raises an exception' do
1468
+ let(:exception) { StandardError.new("Intentional error") }
1469
+
1470
+ it 'logs the error and continues' do
1471
+ emitted_exception = false
1472
+ expect(client_one.logger).to receive(:error).with(/#{exception.message}/)
1473
+ presence_client_one.subscribe do |presence_message|
1474
+ emitted_exception = true
1475
+ raise exception
1476
+ end
1477
+ presence_client_one.enter do
1478
+ EventMachine.add_timer(1) do
1479
+ expect(emitted_exception).to eql(true)
1480
+ stop_reactor
1481
+ end
1482
+ end
1483
+ end
1484
+ end
1466
1485
  end
1467
1486
 
1468
1487
  context '#unsubscribe' do
@@ -612,6 +612,87 @@ describe Ably::Auth do
612
612
  end
613
613
  end
614
614
 
615
+ context 'query_time: true' do
616
+ let(:local_time) { @now - 60 }
617
+ let(:server_time) { @now }
618
+
619
+ before do
620
+ @now = Time.now
621
+ allow(Time).to receive(:now).and_return(local_time)
622
+ end
623
+
624
+ it 'only queries the server time once and then works out the offset, query_time option is never persisted' do
625
+ expect(client).to receive(:time).once.and_return(server_time)
626
+
627
+ auth.authorise({}, query_time: true)
628
+ auth.authorise({}, force: true)
629
+ expect(auth.auth_options).to_not have_key(:query_time)
630
+ end
631
+ end
632
+
633
+ context 'TokenParams argument' do
634
+ let(:default_token_params) { { ttl: 23 } }
635
+
636
+ before do
637
+ auth.authorise default_token_params
638
+ end
639
+
640
+ it 'has no effect on the defaults when null and TokenParam defaults remain the same' do
641
+ old_token = auth.current_token_details
642
+ auth.authorise(nil, force: true)
643
+ expect(old_token).to_not eql(auth.current_token_details)
644
+ expect(auth.token_params[:ttl]).to eql(23)
645
+ end
646
+
647
+ it 'updates defaults when present and all previous configured TokenParams are discarded' do
648
+ old_token = auth.current_token_details
649
+ auth.authorise({ client_id: 'bob' }, { force: true })
650
+ expect(old_token).to_not eql(auth.current_token_details)
651
+ expect(auth.token_params[:ttl]).to_not eql(23)
652
+ expect(auth.token_params[:client_id]).to eql('bob')
653
+ end
654
+
655
+ it 'updates Auth#token_params attribute with an immutable hash' do
656
+ auth.authorise({ client_id: 'bob' }, { force: true })
657
+ expect { auth.token_params['key_name'] = 'new_name' }.to raise_error RuntimeError, /can't modify frozen.*Hash/
658
+ end
659
+ end
660
+
661
+ context 'AuthOptions argument' do
662
+ let(:token_ttl) { 2 }
663
+ let(:auth_callback) { Proc.new do
664
+ auth.create_token_request(ttl: token_ttl)
665
+ end }
666
+ let(:default_auth_options) { { auth_callback: auth_callback } }
667
+
668
+ before do
669
+ stub_const 'Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER', 0 # allow token to be used even if about to expire
670
+ stub_const 'Ably::Auth::TOKEN_DEFAULTS', Ably::Auth::TOKEN_DEFAULTS.merge(renew_token_buffer: 0) # Ensure tokens issued expire immediately after issue
671
+
672
+ auth.authorise(nil, default_auth_options)
673
+ @old_token = auth.current_token_details
674
+ sleep token_ttl + 0.5
675
+ end
676
+
677
+ it 'has no effect on the defaults when null and AuthOptions defaults remain the same' do
678
+ auth.authorise(nil, nil)
679
+ expect(@old_token).to_not eql(auth.current_token_details)
680
+ expect(auth.options[:auth_callback]).to eql(auth_callback)
681
+ end
682
+
683
+ it 'updates defaults when present and all previous configured AuthOptions are discarded' do
684
+ auth.authorise(nil, auth_method: :post)
685
+ expect(@old_token).to_not eql(auth.current_token_details)
686
+ expect(auth.options[:auth_callback]).to be_nil
687
+ expect(auth.options[:auth_method]).to eql(:post)
688
+ end
689
+
690
+ it 'updates Auth#options attribute with an immutable hash' do
691
+ auth.authorise(nil, auth_callback: Proc.new { '1231232.12321:12321312' })
692
+ expect { auth.options['key_name'] = 'new_name' }.to raise_error RuntimeError, /can't modify frozen.*Hash/
693
+ end
694
+ end
695
+
615
696
  context 'with previous authorisation' do
616
697
  before do
617
698
  auth.authorise
@@ -640,10 +721,10 @@ describe Ably::Auth do
640
721
  expect(auth.token_params[:ttl]).to eql(26)
641
722
  end
642
723
 
643
- it 'updates the persisted token params that are then used for subsequent authorise requests' do
644
- expect(auth.options[:query_time]).to_not eql(true)
645
- auth.authorise({}, query_time: true)
646
- expect(auth.options[:query_time]).to eql(true)
724
+ it 'updates the persisted auth options that are then used for subsequent authorise requests' do
725
+ expect(auth.options[:authUrl]).to be_nil
726
+ auth.authorise({}, authUrl: 'http://foo.com')
727
+ expect(auth.options[:authUrl]).to eql('http://foo.com')
647
728
  end
648
729
 
649
730
  context 'with a Proc for the :auth_callback option' do
@@ -893,6 +974,43 @@ describe Ably::Auth do
893
974
  hmac = hmac_for(Ably::Models::TokenRequest(token_request_attributes).attributes, key_secret)
894
975
  expect(subject['mac']).to eql(hmac)
895
976
  end
977
+
978
+ context 'lexicographic ordering of channels and operations' do
979
+ let(:token_attributes) do
980
+ {
981
+ key_name: key_name,
982
+ ttl: 600,
983
+ capability: {
984
+ "channel2" => ["subscribe", "publish"],
985
+ "channel1" => ["subscribe", "history"]
986
+ },
987
+ client_id: random_str,
988
+ nonce: random_str,
989
+ timestamp: Time.now.to_i
990
+ }
991
+ end
992
+
993
+ let(:token_attributes_ordered) do
994
+ token_attributes.merge(capability: {
995
+ "channel1" => ["history", "subscribe"],
996
+ "channel2" => ["publish", "subscribe"]
997
+ })
998
+ end
999
+
1000
+ specify 'HMAC is lexicographic ordered and thus the HMAC is identical' do
1001
+ hmac = auth.create_token_request(token_attributes).mac
1002
+ hmac_ordered = auth.create_token_request(token_attributes_ordered).mac
1003
+ expect(hmac).to eql(hmac_ordered)
1004
+ end
1005
+
1006
+ it 'is valid when used for authentication' do
1007
+ auth_callback = Proc.new do
1008
+ auth.create_token_request(token_attributes)
1009
+ end
1010
+ client = Ably::Rest::Client.new(auth_callback: auth_callback, environment: environment, protocol: protocol)
1011
+ client.auth.authorise
1012
+ end
1013
+ end
896
1014
  end
897
1015
  end
898
1016
 
@@ -545,5 +545,22 @@ describe Ably::Rest::Client do
545
545
  expect(client.auth.options[:auth_url]).to eql(dummy_auth_url)
546
546
  end
547
547
  end
548
+
549
+ context 'version headers', :webmock do
550
+ let(:client_options) { default_options.merge(key: api_key) }
551
+ let!(:publish_message_stub) do
552
+ stub_request(:post, "#{client.endpoint.to_s.gsub('://', "://#{api_key}@")}/channels/foo/publish").
553
+ with(headers: {
554
+ 'X-Ably-Version' => Ably::PROTOCOL_VERSION,
555
+ 'X-Ably-Lib' => "ruby-#{Ably::VERSION}"
556
+ }).
557
+ to_return(status: 201, body: '{}', headers: { 'Content-Type' => 'application/json' })
558
+ end
559
+
560
+ it 'sends a protocol version and lib version header' do
561
+ client.channels.get('foo').publish("event")
562
+ expect(publish_message_stub).to have_been_requested
563
+ end
564
+ end
548
565
  end
549
566
  end
@@ -106,18 +106,18 @@ shared_examples 'a client initializer' do
106
106
  allow_any_instance_of(subject.class).to receive(:auto_connect).and_return(false)
107
107
  end
108
108
 
109
- let(:client_options) { 'app.key:secret' }
109
+ let(:client_options) { 'App.k3y:sec-r3t' }
110
110
 
111
111
  it 'sets the key' do
112
112
  expect(subject.auth.key).to eql(client_options)
113
113
  end
114
114
 
115
115
  it 'sets the key_name' do
116
- expect(subject.auth.key_name).to eql('app.key')
116
+ expect(subject.auth.key_name).to eql('App.k3y')
117
117
  end
118
118
 
119
119
  it 'sets the key_secret' do
120
- expect(subject.auth.key_secret).to eql('secret')
120
+ expect(subject.auth.key_secret).to eql('sec-r3t')
121
121
  end
122
122
 
123
123
  it 'uses basic auth' do
@@ -118,4 +118,32 @@ describe Ably::Models::TokenDetails do
118
118
  end
119
119
  end
120
120
  end
121
+
122
+ context 'to_json' do
123
+ let(:token_json_parsed) { JSON.parse(Ably::Models::TokenDetails(token_attributes).to_json) }
124
+
125
+ context 'with all attributes and values' do
126
+ let(:token_attributes) do
127
+ { token: random_str, capability: random_str, keyName: random_str, issued: Time.now.to_i, expires: Time.now.to_i + 10, clientId: random_str }
128
+ end
129
+
130
+ it 'returns all attributes' do
131
+ token_attributes.each do |key, val|
132
+ expect(token_json_parsed[key.to_s]).to eql(val)
133
+ end
134
+ expect(token_attributes.keys.length).to eql(token_json_parsed.keys.length)
135
+ end
136
+ end
137
+
138
+ context 'with only a token string' do
139
+ let(:token_attributes) do
140
+ { token: random_str }
141
+ end
142
+
143
+ it 'returns populated attributes' do
144
+ expect(token_json_parsed['token']).to eql(token_attributes[:token])
145
+ expect(token_json_parsed.keys.length).to eql(1)
146
+ end
147
+ end
148
+ end
121
149
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ably-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.9
4
+ version: 0.8.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew O'Riordan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-01 00:00:00.000000000 Z
11
+ date: 2016-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday