sfmc-fuelsdk-ruby 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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