restforce 4.1.0 → 4.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4d4058f81fe1d435976494baa2c81caa57515d21f1ffcb0784286d5a608af39
4
- data.tar.gz: ddd80cd062c00f2c9d249e63e2cec5103da55a225c42d443e4370c2d234fae36
3
+ metadata.gz: d1eb25f3f88951d1770c5850c41a9d673d3b0406a76d0c35e54288d52ee5dc00
4
+ data.tar.gz: 51af3a7a4a1e701a4f5e8a79c21452ca5417581aa889188e7f5b5e010fb8f39a
5
5
  SHA512:
6
- metadata.gz: 2b37491f67c8f1494aa849b6118c6b5d0bcfae35ebc5f8e313c68d1989fd4fda486ff661a8dfb74181526958b6baa8cff2b477b7297bdeb9bf98a6e44becfb1f
7
- data.tar.gz: c046776763a2d2bc13890f6c64241052d25d8e1ded812770ef99aa7df407662065f9bbc349c94d902a66cf71d400770b63dd964a355ea9d2cd57cffe3500156f
6
+ metadata.gz: eabc94739d7bbdb2e88fcf3b2ff4bfb3c0b4272f74f50d6fef3f549ca559cd52ab212b5fbd6988da0237257aef7d092b4f654e275a797beb28947b268263f07d
7
+ data.tar.gz: 56ac8e739182f941a45cffe4c8b28364d8b99243128c8c7864820e15e752785af3938c8f99377e3428dcc9a61ac98a72703850675455cc88effe5b68bdca454b
@@ -1,3 +1,7 @@
1
+ ## 4.2.0 (Oct 23, 2019)
2
+
3
+ * Add support for platform events, CDC, generic events, etc. in the Streaming API (@nathanKramer)
4
+
1
5
  ## 4.1.0 (Oct 20, 2019)
2
6
 
3
7
  * Add support for JWT authentication (@nathanKramer, @tagCincy)
data/README.md CHANGED
@@ -25,7 +25,7 @@ Features include:
25
25
 
26
26
  Add this line to your application's Gemfile:
27
27
 
28
- gem 'restforce', '~> 4.1.0'
28
+ gem 'restforce', '~> 4.2.0'
29
29
 
30
30
  And then execute:
31
31
 
@@ -528,8 +528,10 @@ client.get('/services/apexrest/FieldCase', company: 'GenePoint')
528
528
 
529
529
  ### Streaming
530
530
 
531
- Restforce supports the [Streaming API](http://wiki.developerforce.com/page/Getting_Started_with_the_Force.com_Streaming_API), and makes implementing
532
- pub/sub with Salesforce a trivial task:
531
+ Restforce supports the [Streaming API](https://trailhead.salesforce.com/en/content/learn/modules/api_basics/api_basics_streaming), and makes implementing
532
+ pub/sub with Salesforce a trivial task.
533
+
534
+ Here is an example of creating and subscribing to a `PushTopic`:
533
535
 
534
536
  ```ruby
535
537
  # Restforce uses faye as the underlying implementation for CometD.
@@ -553,7 +555,7 @@ client.create!('PushTopic',
553
555
 
554
556
  EM.run do
555
557
  # Subscribe to the PushTopic.
556
- client.subscribe 'AllAccounts' do |message|
558
+ client.subscription '/topic/AllAccounts' do |message|
557
559
  puts message.inspect
558
560
  end
559
561
  end
@@ -574,7 +576,7 @@ that event ID:
574
576
  ```ruby
575
577
  EM.run {
576
578
  # Subscribe to the PushTopic.
577
- client.subscribe 'AllAccounts', replay: 10 do |message|
579
+ client.subscription '/topic/AllAccounts', replay: 10 do |message|
578
580
  puts message.inspect
579
581
  end
580
582
  }
@@ -648,7 +650,7 @@ of the subscription:
648
650
  EM.run {
649
651
  # Subscribe to the PushTopic and use the custom replay handler to store any
650
652
  # received replay ID.
651
- client.subscribe 'AllAccounts', replay: SimpleReplayHandler.new do |message|
653
+ client.subscription '/topic/AllAccounts', replay: SimpleReplayHandler.new do |message|
652
654
  puts message.inspect
653
655
  end
654
656
  }
@@ -5,13 +5,28 @@ module Restforce
5
5
  module Streaming
6
6
  # Public: Subscribe to a PushTopic
7
7
  #
8
- # channels - The name of the PushTopic channel(s) to subscribe to.
8
+ # topics - The name of the PushTopic channel(s) to subscribe to.
9
9
  # block - A block to run when a new message is received.
10
10
  #
11
11
  # Returns a Faye::Subscription
12
- def subscribe(channels, options = {}, &block)
13
- Array(channels).each { |channel| replay_handlers[channel] = options[:replay] }
14
- faye.subscribe Array(channels).map { |channel| "/topic/#{channel}" }, &block
12
+ def legacy_subscribe(topics, options = {}, &block)
13
+ topics = Array(topics).map { |channel| "/topic/#{channel}" }
14
+ subscription(topics, options, &block)
15
+ end
16
+ alias subscribe legacy_subscribe
17
+
18
+ # Public: Subscribe to one or more Streaming API channels
19
+ #
20
+ # channels - The name of the Streaming API (cometD) channel(s) to subscribe to.
21
+ # block - A block to run when a new message is received.
22
+ #
23
+ # Returns a Faye::Subscription
24
+ def subscription(channels, options = {}, &block)
25
+ one_or_more_channels = Array(channels)
26
+ one_or_more_channels.each do |channel|
27
+ replay_handlers[channel] = options[:replay]
28
+ end
29
+ faye.subscribe(one_or_more_channels, &block)
15
30
  end
16
31
 
17
32
  # Public: Faye client to use for subscribing to PushTopics
@@ -49,7 +64,7 @@ module Restforce
49
64
 
50
65
  def incoming(message, callback)
51
66
  callback.call(message).tap do
52
- channel = message.fetch('channel').gsub('/topic/', '')
67
+ channel = message.fetch('channel')
53
68
  replay_id = message.fetch('data', {}).fetch('event', {})['replayId']
54
69
 
55
70
  handler = @replay_handlers[channel]
@@ -64,12 +79,12 @@ module Restforce
64
79
  # Leave non-subscribe messages alone
65
80
  return callback.call(message) unless message['channel'] == '/meta/subscribe'
66
81
 
67
- channel = message['subscription'].gsub('/topic/', '')
82
+ channel = message['subscription']
68
83
 
69
84
  # Set the replay value for the channel
70
85
  message['ext'] ||= {}
71
86
  message['ext']['replay'] = {
72
- "/topic/#{channel}" => replay_id(channel)
87
+ channel => replay_id(channel)
73
88
  }
74
89
 
75
90
  # Carry on and send the message to the server
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Restforce
4
- VERSION = '4.1.0'
4
+ VERSION = '4.2.0'
5
5
  end
@@ -4,18 +4,19 @@ require 'spec_helper'
4
4
 
5
5
  describe Restforce::Concerns::Streaming, event_machine: true do
6
6
  describe '.subscribe' do
7
- let(:channels) { %w[channel1 channel2] }
8
- let(:topics) { channels.map { |c| "/topic/#{c}" } }
7
+ let(:channels) do
8
+ ['/topic/topic1', '/event/MyCustomEvent__e', '/data/ChangeEvents']
9
+ end
9
10
  let(:subscribe_block) { lambda { 'subscribe' } }
10
11
  let(:faye_double) { double('Faye') }
11
12
 
12
13
  it 'subscribes to the topics with faye' do
13
14
  faye_double.
14
15
  should_receive(:subscribe).
15
- with(topics, &subscribe_block)
16
+ with(channels, &subscribe_block)
16
17
  client.stub faye: faye_double
17
18
 
18
- client.subscribe(channels, &subscribe_block)
19
+ client.subscription(channels, &subscribe_block)
19
20
  end
20
21
 
21
22
  context "replay_handlers" do
@@ -25,24 +26,51 @@ describe Restforce::Concerns::Streaming, event_machine: true do
25
26
  }
26
27
 
27
28
  it 'registers nil handlers when no replay option is given' do
28
- client.subscribe(channels, &subscribe_block)
29
- client.replay_handlers.should eq('channel1' => nil, 'channel2' => nil)
29
+ client.subscription(channels, &subscribe_block)
30
+ client.replay_handlers.should eq(
31
+ '/topic/topic1' => nil,
32
+ '/event/MyCustomEvent__e' => nil,
33
+ '/data/ChangeEvents' => nil
34
+ )
30
35
  end
31
36
 
32
37
  it 'registers a replay_handler for each channel given' do
33
- client.subscribe(channels, replay: -2, &subscribe_block)
34
- client.replay_handlers.should eq('channel1' => -2, 'channel2' => -2)
38
+ client.subscription(channels, replay: -2, &subscribe_block)
39
+ client.replay_handlers.should eq(
40
+ '/topic/topic1' => -2,
41
+ '/event/MyCustomEvent__e' => -2,
42
+ '/data/ChangeEvents' => -2
43
+ )
35
44
  end
36
45
 
37
46
  it 'replaces earlier handlers in subsequent calls' do
38
- client.subscribe(%w[channel1 channel2], replay: 2, &subscribe_block)
39
- client.subscribe(%w[channel2 channel3], replay: 3, &subscribe_block)
47
+ client.subscription(
48
+ ['/topic/channel1', '/topic/channel2'],
49
+ replay: 2,
50
+ &subscribe_block
51
+ )
52
+ client.subscription(
53
+ ['/topic/channel2', '/topic/channel3'],
54
+ replay: 3,
55
+ &subscribe_block
56
+ )
57
+
40
58
  client.replay_handlers.should eq(
41
- 'channel1' => 2,
42
- 'channel2' => 3,
43
- 'channel3' => 3
59
+ '/topic/channel1' => 2,
60
+ '/topic/channel2' => 3,
61
+ '/topic/channel3' => 3
44
62
  )
45
63
  end
64
+
65
+ context 'backwards compatibility' do
66
+ it 'it assumes channels are push topics' do
67
+ client.subscribe(%w[channel1 channel2], replay: -2, &subscribe_block)
68
+ client.replay_handlers.should eq(
69
+ '/topic/channel1' => -2,
70
+ '/topic/channel2' => -2
71
+ )
72
+ end
73
+ end
46
74
  end
47
75
  end
48
76
 
@@ -87,41 +115,41 @@ describe Restforce::Concerns::Streaming, event_machine: true do
87
115
  let(:extension) { Restforce::Concerns::Streaming::ReplayExtension.new(handlers) }
88
116
 
89
117
  it 'sends nil without a specified handler' do
90
- output = subscribe(extension, to: "channel1")
118
+ output = subscribe(extension, to: "/topic/channel1")
91
119
  read_replay(output).should eq('/topic/channel1' => nil)
92
120
  end
93
121
 
94
122
  it 'with a scalar replay id' do
95
- handlers['channel1'] = -2
96
- output = subscribe(extension, to: "channel1")
123
+ handlers['/topic/channel1'] = -2
124
+ output = subscribe(extension, to: "/topic/channel1")
97
125
  read_replay(output).should eq('/topic/channel1' => -2)
98
126
  end
99
127
 
100
128
  it 'with a hash' do
101
- hash_handler = { 'channel1' => -1, 'channel2' => -2 }
129
+ hash_handler = { '/topic/channel1' => -1, '/topic/channel2' => -2 }
102
130
 
103
- handlers['channel1'] = hash_handler
104
- handlers['channel2'] = hash_handler
131
+ handlers['/topic/channel1'] = hash_handler
132
+ handlers['/topic/channel2'] = hash_handler
105
133
 
106
- output = subscribe(extension, to: "channel1")
134
+ output = subscribe(extension, to: "/topic/channel1")
107
135
  read_replay(output).should eq('/topic/channel1' => -1)
108
136
 
109
- output = subscribe(extension, to: "channel2")
137
+ output = subscribe(extension, to: "/topic/channel2")
110
138
  read_replay(output).should eq('/topic/channel2' => -2)
111
139
  end
112
140
 
113
141
  it 'with an object' do
114
142
  custom_handler = double('custom_handler')
115
143
  custom_handler.should_receive(:[]).and_return(123)
116
- handlers['channel1'] = custom_handler
144
+ handlers['/topic/channel1'] = custom_handler
117
145
 
118
- output = subscribe(extension, to: "channel1")
146
+ output = subscribe(extension, to: "/topic/channel1")
119
147
  read_replay(output).should eq('/topic/channel1' => 123)
120
148
  end
121
149
 
122
150
  it 'remembers the last replayId' do
123
- handler = { 'channel1' => 41 }
124
- handlers['channel1'] = handler
151
+ handler = { '/topic/channel1' => 41 }
152
+ handlers['/topic/channel1'] = handler
125
153
  message = {
126
154
  'channel' => '/topic/channel1',
127
155
  'data' => {
@@ -130,12 +158,12 @@ describe Restforce::Concerns::Streaming, event_machine: true do
130
158
  }
131
159
 
132
160
  extension.incoming(message, ->(m) {})
133
- handler.should eq('channel1' => 42)
161
+ handler.should eq('/topic/channel1' => 42)
134
162
  end
135
163
 
136
164
  it 'when an incoming message has no replayId' do
137
- handler = { 'channel1' => 41 }
138
- handlers['channel1'] = handler
165
+ handler = { '/topic/channel1' => 41 }
166
+ handlers['/topic/channel1'] = handler
139
167
 
140
168
  message = {
141
169
  'channel' => '/topic/channel1',
@@ -143,7 +171,7 @@ describe Restforce::Concerns::Streaming, event_machine: true do
143
171
  }
144
172
 
145
173
  extension.incoming(message, ->(m) {})
146
- handler.should eq('channel1' => 41)
174
+ handler.should eq('/topic/channel1' => 41)
147
175
  end
148
176
 
149
177
  private
@@ -152,7 +180,7 @@ describe Restforce::Concerns::Streaming, event_machine: true do
152
180
  output = nil
153
181
  message = {
154
182
  'channel' => '/meta/subscribe',
155
- 'subscription' => "/topic/#{options[:to]}"
183
+ 'subscription' => options[:to]
156
184
  }
157
185
  extension.outgoing(message, ->(m) {
158
186
  output = m
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restforce
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric J. Holmes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-10-20 00:00:00.000000000 Z
12
+ date: 2019-10-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday