sfmc-fuelsdk-ruby 1.2.0 → 1.3.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: 3a05834436829d49ca8336cd49946a56bed5f003f709a512a1ecb9637cec3031
4
- data.tar.gz: 8f00eed0dd3e176c72042cf404b0fb7e06b71820f69df8417581c51a90e68869
3
+ metadata.gz: c6d1e7835b46241d74415cfc71fcf04898d24c36b4d7e02ecc2c79c0b4b43851
4
+ data.tar.gz: 6e49a53e6a97bda143d6cae5fb335f50dc793ea0da967c4236f69874137e7f17
5
5
  SHA512:
6
- metadata.gz: a8ee8667e093661ebed4f9433f3de2010079117db931f917ddda8cefb5eef8e511a8857bd457731cb0cb217d46212a0f0b9b71cb41010ea6f3670aafadc50267
7
- data.tar.gz: db4f4acc5d67666bef2a109460fdc018be30f438751968cb235d64663f73b5ec34cb1d8acc18cbd8574760ac3c5205dfe3105a819cade0030527609f51c38007
6
+ metadata.gz: c7f5558179e22d3acf72b562b6ea219f1ffea55946ccab4bd2108e2e471f35102131113c6e4e58ad69801281e24d02a5e174006193ba018d26a14df79c60ec2a
7
+ data.tar.gz: aef480e9c3218532d934d69b9204b71822e7d2ee6c4a2eece74211bf8442196caa241328b43229a6e241b6baabd7130ca7104ace67d9fdd14632f7367deeeca1
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: Bug report
3
+ about: Describe the issue you found
4
+ title: "[BUG]"
5
+ labels: bug
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior.
15
+
16
+ **Expected behavior**
17
+ A clear and concise description of what you expected to happen.
18
+
19
+ **Screenshots**
20
+ If applicable, add screenshots to help explain your problem.
21
+
22
+ **Code snippet**
23
+ A code snippet that demonstrates the issue or a link to a code repository the developers can easily pull down to recreate the issue locally.
24
+
25
+ Note: Because the developers need to copy and paste the code snippet, including a code snippet as a media file (e.g. gif) is not sufficient.
26
+
27
+
28
+ **Environment**
29
+ - SDK Version [e.g. 1.2.0]
30
+ - Ruby version
31
+
32
+ **The bug has the severity**
33
+ - [ ] Critical: The defect affects critical functionality or critical data. It does not have a workaround.
34
+ - [ ] Major: The defect affects major functionality or major data. It has a workaround but is not obvious and is difficult.
35
+ - [ ] Minor: The defect affects minor functionality or non-critical data. It has an easy workaround.
36
+ - [ ] Trivial: The defect does not affect functionality or data. It does not even need a workaround. It does not impact productivity or efficiency. It is merely an inconvenience.
37
+
38
+ **Additional context**
39
+ Add any other context about the problem here.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: "[Enhancement]"
5
+ labels: enhancement
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Is your feature request related to a problem? Please describe**
11
+ A clear and concise description of what the problem is.
12
+
13
+ **Describe the solution you'd like**
14
+ A clear and concise description of what you want to happen.
15
+
16
+ **Describe alternatives you've considered**
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ **Additional context**
20
+ Add any other context or screenshots about the feature request here.
data/.gitignore CHANGED
@@ -8,6 +8,7 @@ lib/bundler/man
8
8
  pkg
9
9
  rdoc
10
10
  spec/reports
11
+ spec/public_or_web_integration_credentials.rb
11
12
  test/tmp
12
13
  test/version_tmp
13
14
  tmp
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sfmc-fuelsdk-ruby (1.2.0)
4
+ sfmc-fuelsdk-ruby (1.3.0)
5
5
  json (~> 1.8, >= 1.8.1)
6
6
  jwt (~> 1.0, >= 1.0.0)
7
7
  savon (= 2.2.0)
data/README.md CHANGED
@@ -6,6 +6,34 @@ ExactTarget Fuel SDK / SalesforceMarektingCloudSDK for Ruby
6
6
  ## Overview ##
7
7
  The Fuel SDK for Ruby provides easy access to ExactTarget's Fuel API Family services, including a collection of REST APIs and a SOAP API. These APIs provide access to ExactTarget functionality via common collection types such as array/hash.
8
8
 
9
+ ## New Features in Version 1.3.0 ##
10
+ - **Added Refresh Token support for OAuth2 authentication**
11
+ - **Added Web/Public App support for OAuth2 authentication**
12
+
13
+ More details on Access Tokens for Web/Public Apps can be found [here](https://developer.salesforce.com/docs/atlas.en-us.mc-app-development.meta/mc-app-development/access-token-app.htm)
14
+
15
+ Example of instantiating the Client class:
16
+
17
+ ```
18
+ myclient = MarketingCloudSDK::Client.new({
19
+ 'client' => {
20
+ 'id' => '<CLIENT_ID>',
21
+ 'secret' => '<CLIENT_SECRET>',
22
+ 'request_token_url' => '<AUTH TENANT SPECIFIC ENDPOINT>',
23
+ 'soap_endpoint' => '<SOAP TENANT SPECIFIC ENDPOINT>',
24
+ 'base_api_url' => '<REST TENANT SPECIFIC ENDPOINT>',
25
+ 'use_oAuth2_authentication' => true,
26
+ 'account_id' => <TARGET_ACCOUNT_ID>,
27
+ 'scope' => '<PERMISSION_LIST>',
28
+ 'application_type' => '<APPLICATION_TYPE>',
29
+ 'redirect_URI' => '<REDIRECT_URI_FOR_PUBLIC/WEB_APP>',
30
+ 'authorization_code' => '<AUTHORIZATION_CODE_FOR_PUBLIC/WEB_APP>'
31
+ }
32
+ })
33
+ ```
34
+
35
+ * application_type can have one of the following values: `server`, `public`, `web`. The default value of application_type is `server`.
36
+
9
37
 
10
38
  ## New Features in Version 1.2.0 ##
11
39
  - **OAuth2 authentication support** - [More Details](https://developer.salesforce.com/docs/atlas.en-us.mc-app-development.meta/mc-app-development/integration-considerations.htm)
@@ -65,7 +93,7 @@ gem build marketingcloudsdk.gemspec
65
93
  Install the newly built gem
66
94
 
67
95
  ```ruby
68
- gem install marketingcloudsdk-1.2.0.gem
96
+ gem install marketingcloudsdk-1.3.0.gem
69
97
  ```
70
98
 
71
99
  If you have not registered your application or you need to lookup your Application Key or Application Signature values, please go to App Center at [Code@: ExactTarget's Developer Community](http://code.exacttarget.com/appcenter "Code@ App Center").
@@ -78,7 +78,7 @@ module MarketingCloudSDK
78
78
  class Client
79
79
  attr_accessor :debug, :access_token, :auth_token, :internal_token, :refresh_token,
80
80
  :id, :secret, :signature, :base_api_url, :package_name, :package_folders, :parent_folders, :auth_token_expiration,
81
- :request_token_url, :soap_endpoint, :use_oAuth2_authentication, :account_id, :scope
81
+ :request_token_url, :soap_endpoint, :use_oAuth2_authentication, :account_id, :scope, :application_type, :authorization_code, :redirect_URI
82
82
 
83
83
  include MarketingCloudSDK::Soap
84
84
  include MarketingCloudSDK::Rest
@@ -86,12 +86,13 @@ module MarketingCloudSDK
86
86
  def jwt= encoded_jwt
87
87
  raise 'Require app signature to decode JWT' unless self.signature
88
88
  decoded_jwt = JWT.decode(encoded_jwt, self.signature, true)
89
+ decoded_jwt_first = decoded_jwt.first
89
90
 
90
- self.auth_token = decoded_jwt['request']['user']['oauthToken']
91
- self.internal_token = decoded_jwt['request']['user']['internalOauthToken']
92
- self.refresh_token = decoded_jwt['request']['user']['refreshToken']
93
- self.auth_token_expiration = Time.new + decoded_jwt['request']['user']['expiresIn']
94
- self.package_name = decoded_jwt['request']['application']['package']
91
+ self.auth_token = decoded_jwt_first['request']['user']['oauthToken']
92
+ self.internal_token = decoded_jwt_first['request']['user']['internalOauthToken']
93
+ self.refresh_token = decoded_jwt_first['request']['user']['refreshToken']
94
+ self.auth_token_expiration = Time.new + decoded_jwt_first['request']['user']['expiresIn']
95
+ self.package_name = decoded_jwt_first['request']['application']['package']
95
96
  end
96
97
 
97
98
  def initialize(params={}, debug=false)
@@ -108,6 +109,9 @@ module MarketingCloudSDK
108
109
  self.use_oAuth2_authentication = client_config["use_oAuth2_authentication"]
109
110
  self.account_id = client_config["account_id"]
110
111
  self.scope = client_config["scope"]
112
+ self.application_type = client_config["application_type"]
113
+ self.authorization_code = client_config["authorization_code"]
114
+ self.redirect_URI = client_config["redirect_URI"]
111
115
  end
112
116
 
113
117
  # Set a default value in case no 'client' params is sent
@@ -123,6 +127,26 @@ module MarketingCloudSDK
123
127
  end
124
128
  end
125
129
 
130
+ if application_type.to_s.strip.empty?
131
+ self.application_type = 'server'
132
+ end
133
+
134
+ if ['web', 'public'].include? application_type
135
+ if authorization_code.to_s.strip.empty? or redirect_URI.to_s.strip.empty?
136
+ raise 'authorization_code or redirect_URI is null: For Public/Web Apps, the authorization_code and redirect_URI must be passed when instantiating Client'
137
+ end
138
+ end
139
+
140
+ if application_type == 'public'
141
+ if id.to_s.strip.empty?
142
+ raise 'id is null: id must be passed when instantiating Client'
143
+ end
144
+ else
145
+ if id.to_s.strip.empty? or secret.to_s.strip.empty?
146
+ raise 'id and secret must pe passed when instantiating Client'
147
+ end
148
+ end
149
+
126
150
  self.jwt = params['jwt'] if params['jwt']
127
151
  self.refresh_token = params['refresh_token'] if params['refresh_token']
128
152
 
@@ -133,7 +157,6 @@ module MarketingCloudSDK
133
157
 
134
158
  def refresh force=false
135
159
  @refresh_mutex.synchronize do
136
- raise 'Require Client Id and Client Secret to refresh tokens' unless (id && secret)
137
160
 
138
161
  if (self.use_oAuth2_authentication == true)
139
162
  self.refreshWithOAuth2(force)
@@ -169,43 +192,67 @@ module MarketingCloudSDK
169
192
  end
170
193
 
171
194
  def refreshWithOAuth2 force=false
172
- raise 'Require Client Id and Client Secret to refresh tokens' unless (id && secret)
173
195
  #If we don't already have a token or the token expires within 5 min(300 seconds)
174
196
  if (self.access_token.nil? || Time.new + 300 > self.auth_token_expiration || force) then
175
- payload = Hash.new.tap do |h|
176
- h['client_id']= id
177
- h['client_secret'] = secret
178
- h['grant_type'] = 'client_credentials'
179
-
180
- if (not self.account_id.to_s.strip.empty?)then
181
- h['account_id'] = account_id
182
- end
183
197
 
184
- if (not self.scope.to_s.strip.empty?)then
185
- h['scope'] = scope
186
- end
187
- end
198
+ payload = createPayload
188
199
 
189
200
  options = Hash.new.tap do |h|
190
201
  h['data'] = payload
191
202
  h['content_type'] = 'application/json'
192
203
  end
193
204
 
194
- self.request_token_url += '/v2/token'
205
+ auth_endpoint = request_token_url + '/v2/token'
195
206
 
196
- response = post(request_token_url, options)
207
+ response = post(auth_endpoint, options)
197
208
  raise "Unable to refresh token: #{response['message']}" unless response.has_key?('access_token')
198
209
 
199
210
  self.access_token = response['access_token']
200
211
  self.auth_token_expiration = Time.new + response['expires_in']
201
212
  self.soap_endpoint = response['soap_instance_url'] + 'service.asmx'
202
213
  self.base_api_url = response['rest_instance_url']
214
+
215
+ if response.has_key?('refresh_token')
216
+ self.refresh_token = response['refresh_token']
217
+ end
218
+
203
219
  return true
204
220
  else
205
221
  return false
206
222
  end
207
223
  end
208
224
 
225
+ def createPayload
226
+ payload = Hash.new.tap do |h|
227
+ h['client_id'] = id
228
+
229
+ if application_type != 'public'
230
+ h['client_secret'] = secret
231
+ end
232
+
233
+ if !refresh_token.to_s.strip.empty?
234
+ h['grant_type'] = 'refresh_token'
235
+ h['refresh_token'] = refresh_token
236
+ elsif ['web', 'public'].include? application_type
237
+ h['grant_type'] = 'authorization_code'
238
+ h['code'] = authorization_code
239
+ h['redirect_uri'] = redirect_URI
240
+ else
241
+ h['grant_type'] = 'client_credentials'
242
+ end
243
+
244
+ unless account_id.to_s.strip.empty?
245
+ h['account_id'] = account_id
246
+ end
247
+
248
+ unless scope.to_s.strip.empty?
249
+ h['scope'] = scope
250
+ end
251
+ end
252
+
253
+ payload
254
+ end
255
+
209
256
  def refresh!
210
257
  refresh true
211
258
  end
@@ -35,5 +35,5 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
35
  =end
36
36
 
37
37
  module MarketingCloudSDK
38
- VERSION = "1.2.0"
38
+ VERSION = "1.3.0"
39
39
  end
data/spec/client_spec.rb CHANGED
@@ -1,94 +1,208 @@
1
1
  require 'spec_helper.rb'
2
+ require 'public_or_web_integration_credentials'
3
+
4
+ def get_test_stub
5
+ {'client' => {
6
+ 'use_oAuth2_authentication' => true,
7
+ 'id' => 'id',
8
+ 'secret' => 'secret',
9
+ 'request_token_url' => 'request_token_url',
10
+ 'account_id' => 'account_id',
11
+ 'authorization_code' => 'authorization_code',
12
+ 'redirect_URI' => 'redirect_URI'
13
+ }}
14
+ end
2
15
 
3
- describe MarketingCloudSDK::Client do
16
+ describe(MarketingCloudSDK::Client) do
4
17
 
5
18
  context 'initialized' do
6
19
 
20
+ before(:each) do
21
+ allow_any_instance_of(MarketingCloudSDK::Client).to receive(:refresh).and_return(true)
22
+ end
23
+
7
24
  it 'with client parameters' do
8
- client = MarketingCloudSDK::Client.new 'client' => {'id' => '1234', 'secret' => 'ssssh', 'signature' => 'hancock',
9
- 'base_api_url' => 'http://getapis', 'request_token_url' => 'http://authapi'}
10
- expect(client.secret).to eq 'ssssh'
11
- expect(client.id).to eq '1234'
12
- expect(client.signature).to eq 'hancock'
13
- expect(client.base_api_url).to eq 'http://getapis'
14
- expect(client.request_token_url).to eq 'http://authapi'
25
+ test_stub = get_test_stub
26
+
27
+ client = MarketingCloudSDK::Client.new(test_stub)
28
+
29
+ expect(client.use_oAuth2_authentication).to be test_stub['client']['use_oAuth2_authentication']
30
+ expect(client.id).to eq test_stub['client']['id']
31
+ expect(client.secret).to eq test_stub['client']['secret']
32
+ expect(client.account_id).to eq test_stub['client']['account_id']
33
+ expect(client.request_token_url).to eq test_stub['client']['request_token_url']
15
34
  end
16
35
 
17
36
  it 'with debug=true' do
18
- client = MarketingCloudSDK::Client.new({}, true)
37
+ client = MarketingCloudSDK::Client.new(get_test_stub, true)
38
+
19
39
  expect(client.debug).to be true
20
40
  end
21
41
 
22
42
  it 'with debug=false' do
23
- client = MarketingCloudSDK::Client.new({}, false)
43
+ client = MarketingCloudSDK::Client.new(get_test_stub, false)
44
+
24
45
  expect(client.debug).to be false
25
46
  end
26
47
 
27
- it 'sets the request_token url to parameter if it exists' do
28
- client = MarketingCloudSDK::Client.new({'request_token_url' => 'fake/url'}, false)
29
- expect(client.request_token_url).to eq 'fake/url'
30
- end
48
+ it 'with base_api_url set to default value if base_api_url is not set' do
49
+ client = MarketingCloudSDK::Client.new(get_test_stub)
31
50
 
32
- it 'sets the base_api_url url to a default if it does not exist' do
33
- client = MarketingCloudSDK::Client.new({}, false)
34
51
  expect(client.base_api_url).to eq 'https://www.exacttargetapis.com'
35
52
  end
36
53
 
37
- it 'sets the request_token url to a default if it does not exist' do
38
- client = MarketingCloudSDK::Client.new({}, false)
39
- expect(client.request_token_url).to eq 'https://auth.exacttargetapis.com/v1/requestToken'
54
+ it 'with null/blank/empty request_token_url and use_oAuth2_authentication=true should raise exception' do
55
+ expected_exception = 'request_token_url (Auth TSE) is mandatory when using OAuth2 authentication'
56
+
57
+ test_stub = get_test_stub
58
+
59
+ [nil, ' ', ''].each do |exception_raiser|
60
+ test_stub['client']['request_token_url'] = exception_raiser
61
+ expect { MarketingCloudSDK::Client.new(test_stub) }.to raise_error(expected_exception)
62
+ end
40
63
  end
41
64
 
42
- it 'creates SoapClient' do
43
- client = MarketingCloudSDK::Client.new
65
+ it 'with SoapClient' do
66
+ client = MarketingCloudSDK::Client.new(get_test_stub)
67
+
44
68
  expect(client).to be_kind_of MarketingCloudSDK::Soap
45
69
  end
46
70
 
47
- it '#wsdl defaults to https://webservice.exacttarget.com/etframework.wsdl' do
48
- client = MarketingCloudSDK::Client.new
71
+ it 'with RestClient' do
72
+ client = MarketingCloudSDK::Client.new(get_test_stub)
73
+
74
+ expect(client).to be_kind_of MarketingCloudSDK::Rest
75
+ end
76
+
77
+ it 'with wsdl set to default value if not set in params' do
78
+ client = MarketingCloudSDK::Client.new(get_test_stub)
79
+
49
80
  expect(client.wsdl).to eq 'https://webservice.exacttarget.com/etframework.wsdl'
50
81
  end
51
82
 
52
- it 'creates RestClient' do
53
- client = MarketingCloudSDK::Client.new
54
- expect(client).to be_kind_of MarketingCloudSDK::Rest
83
+ it 'with application_type set to \'server\' if application_type is not set in params' do
84
+ client = MarketingCloudSDK::Client.new(get_test_stub)
85
+
86
+ expect(client.application_type).to eq 'server'
87
+ end
88
+
89
+ describe 'with web/public app and null/blank/empty authorization_code or redirect_URI should raise exception' do
90
+ expected_exception = 'authorization_code or redirect_URI is null: For Public/Web Apps, the authorization_code and redirect_URI must be passed when instantiating Client'
91
+
92
+ exception_raisers = Hash.new.tap do |h|
93
+ h[nil] = 'nil'
94
+ h[' '] = 'blank string'
95
+ h[''] = 'empty string'
96
+ end
97
+
98
+ test_stub = get_test_stub
99
+
100
+ ['web', 'public'].each do |app_type|
101
+ [nil, ' ', ''].each do |exception_raiser|
102
+ ['authorization_code', 'redirect_URI'].each do |under_test_prop|
103
+
104
+ it "#{app_type} app with #{exception_raisers[exception_raiser]} #{under_test_prop} raises an exception" do
105
+
106
+ test_stub['client']['application_type'] = app_type
107
+ test_stub['client'][under_test_prop] = exception_raiser
108
+
109
+ expect { MarketingCloudSDK::Client.new(test_stub) }.to raise_error(expected_exception)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ it 'with public app and null/blank/empty id should raise exception' do
117
+ expected_exception = 'id is null: id must be passed when instantiating Client'
118
+
119
+ test_stub = get_test_stub
120
+ test_stub['client']['application_type'] = 'public'
121
+ test_stub['client']['authorization_code'] = 'authorization_code'
122
+ test_stub['client']['redirect_URI'] = 'redirect_URI'
123
+
124
+ [nil, ' ', ''].each do |exception_raiser|
125
+ test_stub['client']['id'] = exception_raiser
126
+
127
+ expect { MarketingCloudSDK::Client.new(test_stub) }.to raise_error(expected_exception)
128
+ end
129
+ end
130
+
131
+ describe 'with web/server app and null/blank/empty id or secret should raise exception' do
132
+ expected_exception = 'id and secret must pe passed when instantiating Client'
133
+
134
+ exception_raisers = Hash.new.tap do |h|
135
+ h[nil] = 'nil'
136
+ h[' '] = 'blank string'
137
+ h[''] = 'empty string'
138
+ end
139
+
140
+ test_stub = get_test_stub
141
+ test_stub['client']['authorization_code'] = 'authorization_code'
142
+ test_stub['client']['redirect_URI'] = 'redirect_URI'
143
+
144
+ ['web', 'server'].each do |app_type|
145
+ [nil, ' ', ''].each do |exception_raiser|
146
+ ['id', 'secret'].each do |under_test_prop|
147
+
148
+ it "#{app_type} app with #{exception_raisers[exception_raiser]} #{under_test_prop} raises an exception" do
149
+
150
+ test_stub['client']['application_type'] = app_type
151
+ test_stub['client'][under_test_prop] = exception_raiser
152
+
153
+ expect { MarketingCloudSDK::Client.new(test_stub) }.to raise_error(expected_exception)
154
+ end
155
+ end
156
+ end
157
+ end
55
158
  end
56
159
 
57
160
  describe 'with a wsdl' do
58
161
 
59
- let(:client) { MarketingCloudSDK::Client.new 'defaultwsdl' => 'somewsdl' }
162
+ test_stub = get_test_stub
163
+
164
+ let(:client) { MarketingCloudSDK::Client.new test_stub }
60
165
 
61
166
  it'creates a SoapClient' do
62
167
  expect(client).to be_kind_of MarketingCloudSDK::Soap
63
168
  end
64
169
 
65
170
  it'#wsdl returns default wsdl' do
66
- expect(client.wsdl).to eq 'somewsdl'
171
+ expect(client.wsdl).to eq 'https://webservice.exacttarget.com/etframework.wsdl'
67
172
  end
68
173
  end
69
174
  end
70
175
 
71
176
  context 'instance can set' do
72
177
 
73
- let(:client) { MarketingCloudSDK::Client.new }
178
+ before(:each) do
179
+ allow_any_instance_of(MarketingCloudSDK::Client).to receive(:refresh).and_return(true)
180
+ end
181
+
182
+ let(:client) { MarketingCloudSDK::Client.new (get_test_stub)}
74
183
 
75
184
  it 'client id' do
76
- client.id = 123
77
- expect(client.id).to eq 123
185
+ client.id = 'some_id'
186
+
187
+ expect(client.id).to eq 'some_id'
78
188
  end
79
189
 
80
190
  it 'client secret' do
81
- client.secret = 'sssh'
82
- expect(client.secret).to eq 'sssh'
191
+ client.secret = 'some_secret'
192
+
193
+ expect(client.secret).to eq 'some_secret'
83
194
  end
84
195
 
85
196
  it 'refresh token' do
86
- client.refresh_token = 'refresh'
87
- expect(client.refresh_token).to eq 'refresh'
197
+ client.refresh_token = 'some_refresh_token'
198
+
199
+ expect(client.refresh_token).to eq 'some_refresh_token'
88
200
  end
89
201
 
90
202
  it 'debug' do
203
+ client.debug = false
91
204
  expect(client.debug).to be false
205
+
92
206
  client.debug = true
93
207
  expect(client.debug).to be true
94
208
  end
@@ -97,23 +211,23 @@ describe MarketingCloudSDK::Client do
97
211
  describe '#jwt=' do
98
212
 
99
213
  let(:payload) {
100
- {
101
- 'request' => {
102
- 'user'=> {
103
- 'oauthToken' => 123456789,
104
- 'expiresIn' => 3600,
105
- 'internalOauthToken' => 987654321,
106
- 'refreshToken' => 101010101010
107
- },
108
- 'application'=> {
109
- 'package' => 'JustTesting'
110
- }
214
+ {
215
+ 'request' => {
216
+ 'user'=> {
217
+ 'oauthToken' => 'oAuthToken',
218
+ 'expiresIn' => 3600,
219
+ 'internalOauthToken' => 'internalOauthToken',
220
+ 'refreshToken' => 'refreshToken'
221
+ },
222
+ 'application'=> {
223
+ 'package' => 'JustTesting'
224
+ }
225
+ }
111
226
  }
112
- }
113
227
  }
114
228
 
115
229
  let(:sig){
116
- sig = 'hanckock'
230
+ sig = 'signature'
117
231
  }
118
232
 
119
233
  let(:encoded) {
@@ -121,13 +235,20 @@ describe MarketingCloudSDK::Client do
121
235
  }
122
236
 
123
237
  it 'raises an exception when signature is missing' do
124
- expect { MarketingCloudSDK::Client.new.jwt = encoded }.to raise_exception 'Require app signature to decode JWT'
238
+ test_stub = get_test_stub
239
+ test_stub['jwt'] = encoded
240
+
241
+ expect { MarketingCloudSDK::Client.new test_stub }.to raise_exception 'Require app signature to decode JWT'
125
242
  end
126
243
 
127
244
  describe 'decodes JWT' do
128
245
 
246
+ before(:each) do
247
+ allow_any_instance_of(MarketingCloudSDK::Client).to receive(:refresh).and_return(true)
248
+ end
249
+
129
250
  let(:sig){
130
- sig = 'hanckock'
251
+ sig = 'signature'
131
252
  }
132
253
 
133
254
  let(:encoded) {
@@ -135,84 +256,161 @@ describe MarketingCloudSDK::Client do
135
256
  }
136
257
 
137
258
  let(:client) {
138
- MarketingCloudSDK::Client.new 'client' => { 'id' => '1234', 'secret' => 'ssssh', 'signature' => sig }
259
+ test_stub = get_test_stub
260
+ test_stub['client']['signature'] = sig
261
+ test_stub['jwt'] = encoded
262
+
263
+ MarketingCloudSDK::Client.new test_stub
139
264
  }
140
265
 
141
266
  it 'making auth token available to client' do
142
- client.jwt = encoded
143
- expect(client.auth_token).to eq 123456789
267
+ expect(client.auth_token).to eq payload['request']['user']['oauthToken']
144
268
  end
145
269
 
146
270
  it 'making internal token available to client' do
147
- client.jwt = encoded
148
- expect(client.internal_token).to eq 987654321
271
+ expect(client.internal_token).to eq payload['request']['user']['internalOauthToken']
149
272
  end
150
273
 
151
274
  it 'making refresh token available to client' do
152
- client.jwt = encoded
153
- expect(client.refresh_token).to eq 101010101010
275
+ expect(client.refresh_token).to eq payload['request']['user']['refreshToken']
154
276
  end
155
277
  end
156
278
  end
157
279
 
158
280
  describe '#refresh_token' do
159
- let(:client) { MarketingCloudSDK::Client.new }
281
+
282
+ before(:each) do
283
+ allow_any_instance_of(MarketingCloudSDK::Client).to receive(:refresh).and_return(true)
284
+ end
285
+
286
+ let(:client) { MarketingCloudSDK::Client.new get_test_stub }
160
287
 
161
288
  it 'defaults to nil' do
162
289
  expect(client.refresh_token).to be_nil
163
290
  end
164
291
 
165
292
  it 'can be accessed' do
166
- client.refresh_token = '1234567890'
167
- expect(client.refresh_token).to eq '1234567890'
293
+ client.refresh_token = 'refresh_token'
294
+ expect(client.refresh_token).to eq 'refresh_token'
168
295
  end
169
296
  end
170
297
 
171
- describe '#refresh' do
298
+ context 'authentication payload' do
299
+
300
+ before(:each) do
301
+ allow_any_instance_of(MarketingCloudSDK::Client).to receive(:refresh).and_return(true)
302
+ end
172
303
 
173
- let(:client) { MarketingCloudSDK::Client.new }
304
+ it 'should have public app attributes' do
305
+ test_stub = get_test_stub
306
+ test_stub['client']['application_type'] = 'public'
174
307
 
175
- context 'raises an exception' do
308
+ client = MarketingCloudSDK::Client.new(test_stub)
176
309
 
177
- it 'when client id and secret are missing' do
178
- expect { client.refresh }.to raise_exception 'Require Client Id and Client Secret to refresh tokens'
179
- end
310
+ payload = client.createPayload
180
311
 
181
- it 'when client id is missing' do
182
- client.secret = 1234
183
- expect { client.refresh }.to raise_exception 'Require Client Id and Client Secret to refresh tokens'
184
- end
312
+ expect(client.id).to eq payload['client_id']
313
+ expect(client.redirect_URI).to eq payload['redirect_uri']
314
+ expect(client.authorization_code).to eq payload['code']
315
+ expect('authorization_code').to eq payload['grant_type']
316
+ end
185
317
 
186
- it 'when client secret is missing' do
187
- client.id = 1234
188
- expect { client.refresh }.to raise_exception 'Require Client Id and Client Secret to refresh tokens'
189
- end
318
+ it 'should not have client secret for public app' do
319
+ test_stub = get_test_stub
320
+ test_stub['client']['application_type'] = 'public'
321
+
322
+ client = MarketingCloudSDK::Client.new(test_stub)
323
+
324
+ payload = client.createPayload
325
+
326
+ expect(payload.key?('client_secret')).to be false
327
+ end
328
+
329
+ it 'should have web app attributes' do
330
+ test_stub = get_test_stub
331
+ test_stub['client']['application_type'] = 'web'
332
+
333
+ client = MarketingCloudSDK::Client.new(test_stub)
334
+
335
+ payload = client.createPayload
336
+
337
+ expect('authorization_code').to eq payload['grant_type']
338
+ expect(client.id).to eq payload['client_id']
339
+ expect(client.secret).to eq payload['client_secret']
340
+ expect(client.redirect_URI).to eq payload['redirect_uri']
341
+ expect(client.authorization_code).to eq payload['code']
342
+ end
343
+
344
+ it 'should have server attributes' do
345
+ test_stub = get_test_stub
346
+ test_stub['client']['application_type'] = 'server'
347
+
348
+ client = MarketingCloudSDK::Client.new(test_stub)
349
+
350
+ payload = client.createPayload
351
+
352
+ expect('client_credentials').to eq payload['grant_type']
353
+ expect(client.id).to eq payload['client_id']
354
+ expect(client.secret).to eq payload['client_secret']
355
+ end
356
+
357
+ it 'should not have code and redirect_uri for server app' do
358
+ test_stub = get_test_stub
359
+ test_stub['client']['application_type'] = 'server'
360
+
361
+ client = MarketingCloudSDK::Client.new(test_stub)
362
+
363
+ payload = client.createPayload
364
+
365
+ expect(payload.key?('code')).to be false
366
+ expect(payload.key?('redirect_uri')).to be false
367
+ end
368
+
369
+ it 'should have refresh_token attribute when refresh_token is not null/blank/empty on client' do
370
+ test_stub = get_test_stub
371
+ test_stub['refresh_token'] = 'refresh_token'
372
+ test_stub['client']['application_type'] = 'public'
373
+
374
+ client = MarketingCloudSDK::Client.new(test_stub)
375
+
376
+ payload = client.createPayload
377
+
378
+ expect('refresh_token').to eq payload['grant_type']
379
+ expect(client.refresh_token).to eq payload['refresh_token']
190
380
  end
381
+ end
382
+
383
+ context 'for public and web integrations, access_token and refresh_token' do
384
+ # Test expects a Public/Web App integration config in spec/public_or_web_integration_credentials.rb
385
+ it 'should differ if refresh token is enforced' do
191
386
 
192
- #context 'posts' do
193
- # let(:client) { MarketingCloudSDK::Client.new 'client' => { 'id' => 123, 'secret' => 'sssh'} }
194
- # it 'accessType=offline' do
195
- # client.stub(:post)
196
- # .with({'clientId' => 123, 'secret' => 'ssh', 'accessType' => 'offline'})
197
- # .and_return()
198
- #end
387
+ client = MarketingCloudSDK::Client.new(auth)
199
388
 
200
- #context 'updates' do
201
- # let(:client) { MarketingCloudSDK::Client.new 'client' => { 'id' => 123, 'secret' => 'sssh'} }
389
+ auth_token1 = client.access_token
390
+ refresh_token1 = client.refresh_token
202
391
 
203
- # it 'access_token' do
204
- # #client.stub(:post).
205
- # end
206
- #end
392
+ client.refreshWithOAuth2(true)
393
+
394
+ auth_token2 = client.access_token
395
+ refresh_token2 = client.refresh_token
396
+
397
+ expect(auth_token1).not_to eq(auth_token2)
398
+ expect(refresh_token1).not_to eq(refresh_token2)
399
+ end
207
400
  end
208
401
 
209
402
  describe 'includes HTTPRequest' do
210
403
 
211
- subject { MarketingCloudSDK::Client.new }
404
+ before(:each) do
405
+ allow_any_instance_of(MarketingCloudSDK::Client).to receive(:refresh).and_return(true)
406
+ end
407
+
408
+ subject { MarketingCloudSDK::Client.new get_test_stub}
212
409
 
213
410
  it { should respond_to(:get) }
214
411
  it { should respond_to(:post) }
215
412
  it { should respond_to(:patch) }
216
413
  it { should respond_to(:delete) }
414
+
217
415
  end
218
416
  end
@@ -0,0 +1,12 @@
1
+ def auth
2
+ {
3
+ 'client' => {
4
+ 'id' => '<CLIENT_ID>',
5
+ 'request_token_url' => '<AUTH TENANT SPECIFIC ENDPOINT>',
6
+ 'use_oAuth2_authentication' => true,
7
+ 'application_type' => '<APPLICATION_TYPE>',
8
+ 'redirect_URI' => '<REDIRECT_URI_FOR_PUBLIC/WEB_APP>',
9
+ 'authorization_code' => '<AUTHORIZATION_CODE_FOR_PUBLIC/WEB_APP>'
10
+ }
11
+ }
12
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfmc-fuelsdk-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Salesforce
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-21 00:00:00.000000000 Z
11
+ date: 2019-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -118,22 +118,22 @@ dependencies:
118
118
  name: jwt
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
- - - "~>"
122
- - !ruby/object:Gem::Version
123
- version: '1.0'
124
121
  - - ">="
125
122
  - !ruby/object:Gem::Version
126
123
  version: 1.0.0
124
+ - - "~>"
125
+ - !ruby/object:Gem::Version
126
+ version: '1.0'
127
127
  type: :runtime
128
128
  prerelease: false
129
129
  version_requirements: !ruby/object:Gem::Requirement
130
130
  requirements:
131
- - - "~>"
132
- - !ruby/object:Gem::Version
133
- version: '1.0'
134
131
  - - ">="
135
132
  - !ruby/object:Gem::Version
136
133
  version: 1.0.0
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '1.0'
137
137
  description: API wrapper for SOAP and REST API with Salesforce Marketing Cloud (ExactTarget)
138
138
  email:
139
139
  - mcsdkadmin@salesforce.com
@@ -141,6 +141,8 @@ executables: []
141
141
  extensions: []
142
142
  extra_rdoc_files: []
143
143
  files:
144
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
145
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
144
146
  - ".gitignore"
145
147
  - Gemfile
146
148
  - Gemfile.lock
@@ -193,6 +195,7 @@ files:
193
195
  - spec/http_request_spec.rb
194
196
  - spec/objects_helper_spec.rb
195
197
  - spec/objects_spec.rb
198
+ - spec/public_or_web_integration_credentials.rb.template
196
199
  - spec/rest_spec.rb
197
200
  - spec/soap_spec.rb
198
201
  - spec/spec_helper.rb
@@ -217,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
220
  version: '0'
218
221
  requirements: []
219
222
  rubyforge_project:
220
- rubygems_version: 2.7.6
223
+ rubygems_version: 2.7.8
221
224
  signing_key:
222
225
  specification_version: 4
223
226
  summary: Fuel Client Library for Ruby
@@ -256,6 +259,7 @@ test_files:
256
259
  - spec/http_request_spec.rb
257
260
  - spec/objects_helper_spec.rb
258
261
  - spec/objects_spec.rb
262
+ - spec/public_or_web_integration_credentials.rb.template
259
263
  - spec/rest_spec.rb
260
264
  - spec/soap_spec.rb
261
265
  - spec/spec_helper.rb