mrkt 0.6.2 → 1.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.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/.github/dependabot.yml +11 -0
  3. data/.github/workflows/ruby.yml +41 -0
  4. data/.rubocop.yml +31 -6
  5. data/Gemfile.lock +95 -69
  6. data/LICENSE +21 -0
  7. data/README.md +35 -7
  8. data/lib/mrkt/concerns/authentication.rb +32 -6
  9. data/lib/mrkt/concerns/connection.rb +13 -4
  10. data/lib/mrkt/concerns/crud_activities.rb +32 -0
  11. data/lib/mrkt/concerns/crud_asset_folders.rb +43 -0
  12. data/lib/mrkt/concerns/crud_asset_static_lists.rb +30 -0
  13. data/lib/mrkt/concerns/crud_campaigns.rb +2 -4
  14. data/lib/mrkt/concerns/crud_custom_activities.rb +36 -0
  15. data/lib/mrkt/concerns/crud_custom_objects.rb +14 -15
  16. data/lib/mrkt/concerns/crud_helpers.rb +7 -0
  17. data/lib/mrkt/concerns/crud_leads.rb +41 -15
  18. data/lib/mrkt/concerns/crud_lists.rb +13 -10
  19. data/lib/mrkt/concerns/crud_programs.rb +6 -5
  20. data/lib/mrkt/concerns/import_custom_objects.rb +24 -0
  21. data/lib/mrkt/concerns/import_leads.rb +8 -5
  22. data/lib/mrkt/errors.rb +23 -3
  23. data/lib/mrkt/faraday/params_encoder.rb +20 -0
  24. data/lib/mrkt/faraday.rb +4 -0
  25. data/lib/mrkt/faraday_middleware/response.rb +4 -4
  26. data/lib/mrkt/faraday_middleware.rb +3 -7
  27. data/lib/mrkt/version.rb +1 -1
  28. data/lib/mrkt.rb +29 -3
  29. data/mrkt.gemspec +13 -12
  30. data/spec/concerns/authentication_spec.rb +95 -0
  31. data/spec/concerns/crud_activities_spec.rb +279 -0
  32. data/spec/concerns/crud_asset_folders_spec.rb +273 -0
  33. data/spec/concerns/crud_asset_static_lists_spec.rb +183 -0
  34. data/spec/concerns/crud_custom_activities_spec.rb +172 -0
  35. data/spec/concerns/crud_custom_objects_spec.rb +99 -89
  36. data/spec/concerns/crud_leads_spec.rb +151 -1
  37. data/spec/concerns/crud_lists_spec.rb +33 -0
  38. data/spec/concerns/import_custom_objects_spec.rb +89 -0
  39. data/spec/concerns/import_leads_spec.rb +3 -3
  40. data/spec/faraday/params_encoder_spec.rb +24 -0
  41. data/spec/spec_helper.rb +3 -6
  42. data/spec/support/initialized_client.rb +1 -1
  43. data/spec/support/webmock.rb +1 -7
  44. metadata +82 -40
  45. data/.travis.yml +0 -8
@@ -1,52 +1,51 @@
1
1
  module Mrkt
2
2
  module CrudCustomObjects
3
- def get_list_of_custom_objects(names=nil)
3
+ def get_list_of_custom_objects(names = nil)
4
4
  params = {}
5
- params[:names] = names.join(',') if names
5
+ params[:names] = names if names
6
6
 
7
7
  get('/rest/v1/customobjects.json', params)
8
8
  end
9
9
 
10
10
  def describe_custom_object(name)
11
- fail Mrkt::Errors::Unknown unless name
11
+ raise Mrkt::Errors::Unknown unless name
12
12
 
13
13
  get("/rest/v1/customobjects/#{name}/describe.json")
14
14
  end
15
15
 
16
16
  def createupdate_custom_objects(name, input, action: 'createOrUpdate', dedupe_by: 'dedupeFields')
17
- post("/rest/v1/customobjects/#{name}.json") do |req|
18
- params = {
17
+ post_json("/rest/v1/customobjects/#{name}.json") do
18
+ {
19
19
  input: input,
20
20
  action: action,
21
21
  dedupeBy: dedupe_by
22
22
  }
23
- json_payload(req, params)
24
23
  end
25
24
  end
26
25
 
27
26
  def delete_custom_objects(name, input, delete_by: 'dedupeFields')
28
- post("/rest/v1/customobjects/#{name}/delete.json") do |req|
29
- params = {
27
+ post_json("/rest/v1/customobjects/#{name}/delete.json") do
28
+ {
30
29
  input: input,
31
30
  deleteBy: delete_by
32
31
  }
33
-
34
- json_payload(req, params)
35
32
  end
36
33
  end
37
34
 
38
35
  def get_custom_objects(name, input, filter_type: 'dedupeFields', fields: nil, next_page_token: nil, batch_size: nil)
39
- post("/rest/v1/customobjects/#{name}.json?_method=GET") do |req|
36
+ post_json("/rest/v1/customobjects/#{name}.json?_method=GET") do
40
37
  params = {
41
38
  input: input,
42
39
  filterType: filter_type
43
40
  }
44
41
 
45
- params[:fields] = fields if fields
46
- params[:nextPageToken] = next_page_token if next_page_token
47
- params[:batchSize] = batch_size if batch_size
42
+ optional = {
43
+ fields: fields,
44
+ nextPageToken: next_page_token,
45
+ batchSize: batch_size
46
+ }
48
47
 
49
- json_payload(req, params)
48
+ merge_params(params, optional)
50
49
  end
51
50
  end
52
51
  end
@@ -4,6 +4,13 @@ module Mrkt
4
4
  lead_ids.map { |id| { id: id } }
5
5
  end
6
6
 
7
+ def post_json(url)
8
+ post(url) do |req|
9
+ payload = block_given? ? yield(req) : {}
10
+ json_payload(req, payload)
11
+ end
12
+ end
13
+
7
14
  def json_payload(req, payload)
8
15
  req.headers[:content_type] = 'application/json'
9
16
  req.body = JSON.generate(payload)
@@ -1,28 +1,42 @@
1
1
  module Mrkt
2
2
  module CrudLeads
3
+ def get_lead_by_id(id, fields: nil)
4
+ optional = {
5
+ fields: fields
6
+ }
7
+
8
+ get("/rest/v1/lead/#{id}.json", {}, optional)
9
+ end
10
+
3
11
  def get_leads(filter_type, filter_values, fields: nil, batch_size: nil, next_page_token: nil)
4
12
  params = {
5
13
  filterType: filter_type,
6
- filterValues: filter_values.join(',')
14
+ filterValues: filter_values
7
15
  }
8
- params[:fields] = fields if fields
9
- params[:batchSize] = batch_size if batch_size
10
- params[:nextPageToken] = next_page_token if next_page_token
11
16
 
12
- get('/rest/v1/leads.json', params)
17
+ optional = {
18
+ fields: fields,
19
+ batchSize: batch_size,
20
+ nextPageToken: next_page_token
21
+ }
22
+
23
+ get('/rest/v1/leads.json', params, optional)
13
24
  end
14
25
 
15
26
  def createupdate_leads(leads, action: 'createOrUpdate', lookup_field: nil, partition_name: nil, async_processing: nil)
16
- post('/rest/v1/leads.json') do |req|
27
+ post_json('/rest/v1/leads.json') do
17
28
  params = {
18
29
  action: action,
19
30
  input: leads
20
31
  }
21
- params[:lookupField] = lookup_field if lookup_field
22
- params[:partitionName] = partition_name if partition_name
23
- params[:asyncProcessing] = async_processing if async_processing
24
32
 
25
- json_payload(req, params)
33
+ optional = {
34
+ lookupField: lookup_field,
35
+ partitionName: partition_name,
36
+ asyncProcessing: async_processing
37
+ }
38
+
39
+ merge_params(params, optional)
26
40
  end
27
41
  end
28
42
 
@@ -33,12 +47,24 @@ module Mrkt
33
47
  end
34
48
 
35
49
  def associate_lead(id, cookie)
36
- params = Faraday::Utils::ParamsHash.new
37
- params[:cookie] = cookie
50
+ params = Mrkt::Faraday::ParamsEncoder.encode(cookie: cookie)
38
51
 
39
- post("/rest/v1/leads/#{id}/associate.json?#{params.to_query}") do |req|
40
- json_payload(req, {})
41
- end
52
+ post_json("/rest/v1/leads/#{id}/associate.json?#{params}")
53
+ end
54
+
55
+ def merge_leads(winning_lead_id, losing_lead_ids, merge_in_crm: false)
56
+ params = {}
57
+
58
+ params[:mergeInCRM] = merge_in_crm
59
+ params[:leadIds] = losing_lead_ids if losing_lead_ids
60
+
61
+ query_params = Mrkt::Faraday::ParamsEncoder.encode(params)
62
+
63
+ post_json("/rest/v1/leads/#{winning_lead_id}/merge.json?#{query_params}")
64
+ end
65
+
66
+ def describe_lead
67
+ get('/rest/v1/leads/describe.json')
42
68
  end
43
69
  end
44
70
  end
@@ -1,21 +1,24 @@
1
1
  module Mrkt
2
2
  module CrudLists
3
3
  def get_leads_by_list(list_id, fields: nil, batch_size: nil, next_page_token: nil)
4
- params = {}
5
- params[:fields] = fields if fields
6
- params[:batchSize] = batch_size if batch_size
7
- params[:nextPageToken] = next_page_token if next_page_token
4
+ optional = {
5
+ fields: fields,
6
+ batchSize: batch_size,
7
+ nextPageToken: next_page_token
8
+ }
8
9
 
9
- get("/rest/v1/list/#{list_id}/leads.json", params)
10
+ get("/rest/v1/list/#{list_id}/leads.json", {}, optional)
10
11
  end
11
12
 
12
13
  def add_leads_to_list(list_id, lead_ids)
13
- post("/rest/v1/lists/#{list_id}/leads.json") do |req|
14
- params = {
15
- input: map_lead_ids(lead_ids)
16
- }
14
+ post_json("/rest/v1/lists/#{list_id}/leads.json") do
15
+ { input: map_lead_ids(lead_ids) }
16
+ end
17
+ end
17
18
 
18
- json_payload(req, params)
19
+ def remove_leads_from_list(list_id, lead_ids)
20
+ delete("/rest/v1/lists/#{list_id}/leads.json") do |req|
21
+ json_payload(req, input: map_lead_ids(lead_ids))
19
22
  end
20
23
  end
21
24
  end
@@ -1,12 +1,13 @@
1
1
  module Mrkt
2
2
  module CrudPrograms
3
3
  def browse_programs(offset: nil, max_return: nil, status: nil)
4
- params = {}
5
- params[:offset] = offset if offset
6
- params[:maxReturn] = max_return if max_return
7
- params[:status] = status if status
4
+ optional = {
5
+ offset: offset,
6
+ maxReturn: max_return,
7
+ status: status
8
+ }
8
9
 
9
- get('/rest/asset/v1/programs.json', params)
10
+ get('/rest/asset/v1/programs.json', {}, optional)
10
11
  end
11
12
 
12
13
  def get_program_by_id(id)
@@ -0,0 +1,24 @@
1
+ module Mrkt
2
+ module ImportCustomObjects
3
+ def import_custom_object(file, custom_object, format = 'csv')
4
+ params = {
5
+ format: format,
6
+ file: ::Faraday::UploadIO.new(file, 'text/csv')
7
+ }
8
+
9
+ post("/bulk/v1/customobjects/#{custom_object}/import.json", params)
10
+ end
11
+
12
+ def import_custom_object_status(id, custom_object)
13
+ get("/bulk/v1/customobjects/#{custom_object}/import/#{id}/status.json")
14
+ end
15
+
16
+ def import_custom_object_failures(id, custom_object)
17
+ get("/bulk/v1/customobjects/#{custom_object}/import/#{id}/failures.json")
18
+ end
19
+
20
+ def import_custom_object_warnings(id, custom_object)
21
+ get("/bulk/v1/customobjects/#{custom_object}/import/#{id}/warnings.json")
22
+ end
23
+ end
24
+ end
@@ -3,13 +3,16 @@ module Mrkt
3
3
  def import_lead(file, format = 'csv', lookup_field: nil, list_id: nil, partition_name: nil)
4
4
  params = {
5
5
  format: format,
6
- file: Faraday::UploadIO.new(file, 'text/csv')
6
+ file: ::Faraday::UploadIO.new(file, 'text/csv')
7
7
  }
8
- params[:lookupField] = lookup_field if lookup_field
9
- params[:listId] = list_id if list_id
10
- params[:partitionName] = partition_name if partition_name
11
8
 
12
- post('/bulk/v1/leads.json', params)
9
+ optional = {
10
+ lookupField: lookup_field,
11
+ listId: list_id,
12
+ partitionName: partition_name
13
+ }
14
+
15
+ post('/bulk/v1/leads.json', params, optional)
13
16
  end
14
17
 
15
18
  def import_lead_status(id)
data/lib/mrkt/errors.rb CHANGED
@@ -25,6 +25,7 @@ class Mrkt::Errors
25
25
  610 => 'RequestedResourceNotFound',
26
26
  611 => 'System',
27
27
  612 => 'InvalidContentType',
28
+ 702 => 'RecordNotFound',
28
29
  703 => 'DisabledFeature',
29
30
  1001 => 'TypeMismatch',
30
31
  1002 => 'MissingParamater',
@@ -39,10 +40,29 @@ class Mrkt::Errors
39
40
  1011 => 'FieldNotSupported',
40
41
  1012 => 'InvalidCookieValue',
41
42
  1013 => 'ObjectNotFound',
42
- 1014 => 'FailedToCreateObject'
43
- }
43
+ 1014 => 'FailedToCreateObject',
44
+ 1015 => 'LeadNotInList',
45
+ 1016 => 'TooManyImports',
46
+ 1017 => 'ObjectAlreadyExists',
47
+ 1018 => 'CRMEnabled',
48
+ 1019 => 'ImportInProgress',
49
+ 1020 => 'TooManyCloneToProgram',
50
+ 1021 => 'CompanyUpdateNotAllowed',
51
+ 1022 => 'ObjectInUse',
52
+ 1025 => 'ProgramStatusNotFound',
53
+ 1026 => 'CustomObjectNotEnabled',
54
+ 1027 => 'MaxActivityTypeLimitReached',
55
+ 1028 => 'MaxFieldLimitReached',
56
+ 1029 => 'BulkExportQuotaExceeded',
57
+ 1035 => 'UnsupportedFilterType',
58
+ 1036 => 'DuplicateObjectFoundInInput',
59
+ 1042 => 'InvalidRunAtDate',
60
+ 1048 => 'CustomObjectDiscardDraftFailed',
61
+ 1049 => 'FailedToCreateActivity',
62
+ 1077 => 'MergeLeadsCallFailedDueToFieldLength'
63
+ }.freeze
44
64
 
45
- RESPONSE_CODE_TO_ERROR.values.each do |class_name|
65
+ RESPONSE_CODE_TO_ERROR.each_value do |class_name|
46
66
  const_set(class_name, create_class)
47
67
  end
48
68
 
@@ -0,0 +1,20 @@
1
+ module Mrkt
2
+ module Faraday
3
+ class ParamsEncoder
4
+ class << self
5
+ def encode(hash)
6
+ new_hash = hash.transform_values { |v| encode_value(v) }
7
+ ::Faraday::NestedParamsEncoder.encode(new_hash)
8
+ end
9
+
10
+ def decode(string)
11
+ ::Faraday::NestedParamsEncoder.decode(string)
12
+ end
13
+
14
+ def encode_value(value)
15
+ value.respond_to?(:join) ? value.join(',') : value
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ require 'faraday'
2
+
3
+ require 'mrkt/faraday/params_encoder'
4
+ require 'mrkt/faraday_middleware'
@@ -12,8 +12,8 @@ module Mrkt
12
12
 
13
13
  data = env[:body]
14
14
 
15
- fail Mrkt::Errors::EmptyResponse if data.nil?
16
- fail Mrkt::Errors::Error, data[:error_description] if data.key?(:error)
15
+ raise Mrkt::Errors::EmptyResponse if data.nil?
16
+ raise Mrkt::Errors::Error, data[:error_description] if data.key?(:error)
17
17
 
18
18
  handle_errors!(data[:errors]) unless data.fetch(:success, true)
19
19
  end
@@ -21,8 +21,8 @@ module Mrkt
21
21
  def handle_errors!(errors)
22
22
  error = errors.first
23
23
 
24
- fail Mrkt::Errors::Unknown if error.nil?
25
- fail Mrkt::Errors.find_by_response_code(error[:code].to_i), error[:message]
24
+ raise Mrkt::Errors::Unknown if error.nil?
25
+ raise Mrkt::Errors.find_by_response_code(error[:code].to_i), error[:message]
26
26
  end
27
27
  end
28
28
  end
@@ -1,11 +1,7 @@
1
- require 'faraday'
1
+ require 'mrkt/faraday_middleware/response'
2
2
 
3
3
  module Mrkt
4
- module FaradayMiddleware
5
- autoload :Response, 'mrkt/faraday_middleware/response'
6
- end
7
-
8
- if Faraday::Middleware.respond_to? :register_middleware
9
- Faraday::Response.register_middleware mkto: -> { Mrkt::FaradayMiddleware::Response }
4
+ if ::Faraday::Middleware.respond_to?(:register_middleware)
5
+ ::Faraday::Response.register_middleware(mkto: Mrkt::FaradayMiddleware::Response)
10
6
  end
11
7
  end
data/lib/mrkt/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mrkt
2
- VERSION = '0.6.2'
2
+ VERSION = '1.2.0'.freeze
3
3
  end
data/lib/mrkt.rb CHANGED
@@ -4,24 +4,34 @@ require 'mrkt/errors'
4
4
  require 'mrkt/concerns/connection'
5
5
  require 'mrkt/concerns/authentication'
6
6
  require 'mrkt/concerns/crud_helpers'
7
+ require 'mrkt/concerns/crud_activities'
7
8
  require 'mrkt/concerns/crud_campaigns'
8
9
  require 'mrkt/concerns/crud_leads'
9
10
  require 'mrkt/concerns/crud_lists'
10
11
  require 'mrkt/concerns/import_leads'
12
+ require 'mrkt/concerns/import_custom_objects'
11
13
  require 'mrkt/concerns/crud_custom_objects'
14
+ require 'mrkt/concerns/crud_custom_activities'
12
15
  require 'mrkt/concerns/crud_programs'
16
+ require 'mrkt/concerns/crud_asset_static_lists'
17
+ require 'mrkt/concerns/crud_asset_folders'
13
18
 
14
19
  module Mrkt
15
20
  class Client
16
21
  include Connection
17
22
  include Authentication
18
23
  include CrudHelpers
24
+ include CrudActivities
19
25
  include CrudCampaigns
20
26
  include CrudLeads
21
27
  include CrudLists
22
28
  include ImportLeads
29
+ include ImportCustomObjects
23
30
  include CrudCustomObjects
31
+ include CrudCustomActivities
24
32
  include CrudPrograms
33
+ include CrudAssetStaticLists
34
+ include CrudAssetFolders
25
35
 
26
36
  attr_accessor :debug
27
37
 
@@ -30,17 +40,33 @@ module Mrkt
30
40
 
31
41
  @client_id = options.fetch(:client_id)
32
42
  @client_secret = options.fetch(:client_secret)
43
+ @partner_id = options[:partner_id]
44
+
45
+ @retry_authentication = options.fetch(:retry_authentication, false)
46
+ @retry_authentication_count = options.fetch(:retry_authentication_count, 3).to_i
47
+ @retry_authentication_wait_seconds = options.fetch(:retry_authentication_wait_seconds, 0).to_i
48
+
49
+ @debug = options[:debug]
50
+
51
+ @logger = options[:logger]
52
+ @log_options = options[:log_options]
33
53
 
34
54
  @options = options
35
55
  end
36
56
 
37
- %i(get post delete).each do |http_method|
38
- define_method(http_method) do |path, payload = {}, &block|
57
+ def merge_params(params, optional)
58
+ params.merge(optional.keep_if { |_key, value| value })
59
+ end
60
+
61
+ %i[get post delete].each do |http_method|
62
+ define_method(http_method) do |path, params = {}, optional = {}, &block|
39
63
  authenticate!
40
64
 
65
+ payload = merge_params(params, optional)
66
+
41
67
  resp = connection.send(http_method, path, payload) do |req|
42
68
  add_authorization(req)
43
- block.call(req) unless block.nil?
69
+ block&.call(req)
44
70
  end
45
71
 
46
72
  resp.body
data/mrkt.gemspec CHANGED
@@ -1,5 +1,4 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'mrkt/version'
5
4
 
@@ -16,18 +15,20 @@ Gem::Specification.new do |spec|
16
15
  spec.files = `git ls-files`.split($RS)
17
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = %w(lib)
18
+ spec.require_paths = %w[lib]
20
19
 
21
- spec.required_ruby_version = '~> 2.0'
20
+ spec.required_ruby_version = '>= 2.5'
22
21
 
23
- spec.add_dependency 'faraday_middleware', '> 0.9.0', '< 0.11.0'
22
+ spec.add_dependency 'faraday', '~> 1.0'
23
+ spec.add_dependency 'faraday_middleware', '~> 1.0'
24
24
 
25
- spec.add_development_dependency 'bundler', '~> 1.3'
26
- spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'bundler', '~> 2.0'
26
+ spec.add_development_dependency 'gem-release', '~> 2.1'
27
+ spec.add_development_dependency 'pry-byebug', '~> 3.7'
28
+ spec.add_development_dependency 'rake', '~> 13.0'
27
29
  spec.add_development_dependency 'rspec', '~> 3.2'
28
- spec.add_development_dependency 'webmock', '~> 1.21.0'
29
- spec.add_development_dependency 'simplecov', '~> 0.10.0'
30
- spec.add_development_dependency 'pry-byebug', '~> 3.1.0'
31
- spec.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.7'
32
- spec.add_development_dependency 'rubocop', '~> 0.32.1'
30
+ spec.add_development_dependency 'rubocop', '~> 1.20.0'
31
+ spec.add_development_dependency 'rubocop-rake', '~> 0.6.0'
32
+ spec.add_development_dependency 'simplecov', '~> 0.21.2'
33
+ spec.add_development_dependency 'webmock', '~> 3.1'
33
34
  end
@@ -22,6 +22,101 @@ describe Mrkt::Authentication do
22
22
  end
23
23
  end
24
24
 
25
+ describe '#authenticate!' do
26
+ it 'should authenticate and then be authenticated?' do
27
+ expect(client.authenticated?).to_not be true
28
+ client.authenticate!
29
+ expect(client.authenticated?).to be true
30
+ end
31
+
32
+ context 'with optional partner_id client option' do
33
+ before { remove_request_stub(@authentication_request_stub) }
34
+
35
+ let(:partner_id) { SecureRandom.uuid }
36
+
37
+ let(:client_options) do
38
+ {
39
+ host: host,
40
+ client_id: client_id,
41
+ client_secret: client_secret,
42
+ partner_id: partner_id
43
+ }
44
+ end
45
+
46
+ let(:query) do
47
+ {
48
+ client_id: client_id,
49
+ client_secret: client_secret,
50
+ partner_id: partner_id,
51
+ grant_type: 'client_credentials'
52
+ }
53
+ end
54
+
55
+ subject(:client) { Mrkt::Client.new(client_options) }
56
+
57
+ before do
58
+ stub_request(:get, "https://#{host}/identity/oauth/token")
59
+ .with(query: query)
60
+ .to_return(json_stub(authentication_stub))
61
+ end
62
+
63
+ it 'should authenticate and then be authenticated?' do
64
+ expect(client.authenticated?).to_not be true
65
+ client.authenticate!
66
+ expect(client.authenticated?).to be true
67
+ end
68
+ end
69
+
70
+ context 'when the token has expired and @retry_authentication = true' do
71
+ before { remove_request_stub(@authentication_request_stub) }
72
+
73
+ let(:retry_count) { 3 }
74
+
75
+ let(:expired_authentication_stub) do
76
+ { access_token: SecureRandom.uuid, token_type: 'bearer', expires_in: 0, scope: 'RestClient' }
77
+ end
78
+
79
+ let(:valid_authentication_stub) do
80
+ { access_token: SecureRandom.uuid, token_type: 'bearer', expires_in: 1234, scope: 'RestClient' }
81
+ end
82
+
83
+ let(:client_options) do
84
+ {
85
+ host: host,
86
+ client_id: client_id,
87
+ client_secret: client_secret,
88
+ retry_authentication: true,
89
+ retry_authentication_count: retry_count
90
+ }
91
+ end
92
+
93
+ subject(:client) { Mrkt::Client.new(client_options) }
94
+
95
+ before do
96
+ stub_request(:get, "https://#{host}/identity/oauth/token")
97
+ .with(query: { client_id: client_id, client_secret: client_secret, grant_type: 'client_credentials' })
98
+ .to_return(json_stub(expired_authentication_stub)).times(3).then
99
+ .to_return(json_stub(valid_authentication_stub))
100
+ end
101
+
102
+ it 'should retry until getting valid token and then be authenticated?' do
103
+ expect(client.authenticated?).to_not be true
104
+ client.authenticate!
105
+ expect(client.authenticated?).to be true
106
+ end
107
+
108
+ context 'when retry_authentication_count is low' do
109
+ let(:retry_count) { 2 }
110
+
111
+ it 'should stop retrying after @retry_authentication_count tries and then raise an error' do
112
+ expect(client.authenticated?).to_not be true
113
+
114
+ expect { client.authenticate! }.to raise_error(Mrkt::Errors::Error, 'Client not authenticated')
115
+ end
116
+ end
117
+ end
118
+ end
119
+
25
120
  describe '#authenticated?' do
26
121
  subject { client.authenticated? }
27
122