soapy_cake 1.21.0 → 1.22.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
  SHA1:
3
- metadata.gz: 9a66e1c42c1689312ec741c7ca995566d85e5aba
4
- data.tar.gz: a2bf186bbde7a7373798b2805c987a93181ed584
3
+ metadata.gz: 56f71b18325d9c37c28fa1eb52a36785b29cbde1
4
+ data.tar.gz: 489dfd14ad0e7fe93571ae955544830dced450c1
5
5
  SHA512:
6
- metadata.gz: 9b10715b6a53bd27bc8f7eec15bd821f310e86d9ed5e65391997c6d18660d61ab8f0199f07d1f1787f1d7877d0b5d92028aaff32f4ec447b0eda92b8f36ce4e5
7
- data.tar.gz: 56f798c3dac1384e86d44608ec97c995157c47b86f11357a4f4f537bf5e70b360d8414ea1bc342d509cad98c3b5d1ce4df526523640466255d6377a23f3c0fc3
6
+ metadata.gz: ea22778f46a5c0097f0b182c1f84cff5c509694011dabde1c2794f505a713fa5abae06efe7009c479e81fb4e90cfef16962bb2ea181da0f2dbb4df98a60331d2
7
+ data.tar.gz: 0ce89c5f006bc80e3daafd7a46cecba01ced9fef6a61afc33a617dd2d820b68b67be0c7e6990ac35a1e829f078dc04750be186ede15c2fbbbf67a554824d17d8
data/Gemfile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  source 'https://rubygems.org'
2
3
 
3
4
  gemspec
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'bundler/gem_tasks'
2
3
  require 'rspec/core/rake_task'
3
4
  require 'rubocop-ci'
data/api.yml ADDED
@@ -0,0 +1,187 @@
1
+ ---
2
+ versions:
3
+ admin:
4
+ accounting:
5
+ mark_affiliate_bill_as_received: 1
6
+ export_advertiser_bills: 1
7
+ export_affiliate_bills: 1
8
+ mark_affiliate_bill_as_paid: 1
9
+ add:
10
+ advertiser_credit: 1
11
+ creative: 1
12
+ manual_credit: 1
13
+ addedit:
14
+ advertiser: 1
15
+ advertiser_credit_limit: 1
16
+ affiliate: 2
17
+ apply_suppression_list_to_offer: 1
18
+ blacklist: 1
19
+ campaign: 3
20
+ caps: 1
21
+ contact: 2
22
+ creative: 1
23
+ creative_files: 1
24
+ exchange_rates: 1
25
+ geo_targets: 2
26
+ offer: 5
27
+ offer_contract: 1
28
+ offer_tiers: 1
29
+ remove_blacklist: 1
30
+ suppresion_list: 1
31
+ vertical: 1
32
+ auth:
33
+ login: 2
34
+ doc:
35
+ posting_doc: 1
36
+ edit:
37
+ buyer: 1
38
+ export:
39
+ advertisers: 5
40
+ affiliate_referrals: 1
41
+ affiliates: 5
42
+ blacklists: 1
43
+ buyer_contracts: 1
44
+ buyers: 1
45
+ campaigns: 6
46
+ creatives: 3
47
+ offers: 5
48
+ rules_targets: 3
49
+ schedules: 1
50
+ get:
51
+ account_statuses: 1
52
+ advertisers: 1
53
+ affiliate_tags: 1
54
+ affiliate_tiers: 1
55
+ billing_cycles: 1
56
+ blacklist_reasons: 1
57
+ cap_intervals: 1
58
+ cap_types: 1
59
+ countries: 1
60
+ currencies: 1
61
+ departments: 1
62
+ exchange_rates: 1
63
+ get_api_key: 1
64
+ inactive_reasons: 1
65
+ languages: 1
66
+ offer_statuses: 1
67
+ offer_types: 1
68
+ payment_settings: 1
69
+ payment_types: 1
70
+ price_formats: 1
71
+ roles: 1
72
+ tracking_domains: 1
73
+ verticals: 2
74
+ reports:
75
+ advertiser_summary: 2
76
+ affiliate_summary: 2
77
+ campaign_summary: 2
78
+ creative_summary: 2
79
+ caps: 4
80
+ clicks: 7
81
+ conversion_changes: 10
82
+ conversions: 11
83
+ daily_summary_export: 1
84
+ leads_by_affiliate_export: 1
85
+ leads_by_buyer: 4
86
+ login_export: 1
87
+ offer_summary: 2
88
+ traffic_export: 1
89
+ signup:
90
+ advertiser: 1
91
+ affiliate: 4
92
+ get_media_types: 1
93
+ get_price_formats: 1
94
+ get_traffic_types: 1
95
+ get_vertical_categories: 1
96
+ track:
97
+ accepted_dispositions: 1
98
+ conversion_dispositions: 2
99
+ decrypt_affiliate_link: 1
100
+ mass_conversion_adjustment: 2
101
+ # Version 2 returns an error about an invalid action, so using version 1
102
+ mass_conversion_insert: 1
103
+ rejected_dispositions: 1
104
+ update_conversion: 4
105
+ update_conversion_disposition: 2
106
+ update_conversion_price: 2
107
+ update_conversion_revenue: 1
108
+ update_lead_price: 2
109
+ update_sale_revenue: 1
110
+ affiliate:
111
+ reports:
112
+ bills: 3
113
+ offers:
114
+ offer_feed: 4
115
+
116
+ # Whitelist of read-only actions (don't modify CAKE data).
117
+ read_only:
118
+ admin:
119
+ accounting:
120
+ - export_advertiser_bills
121
+ - export_affiliate_bills
122
+ export:
123
+ - advertisers
124
+ - affiliate_referrals
125
+ - affiliates
126
+ - blacklists
127
+ - buyer_contracts
128
+ - buyers
129
+ - campaigns
130
+ - creatives
131
+ - offers
132
+ - rules_targets
133
+ - schedules
134
+ get:
135
+ - account_statuses
136
+ - advertisers
137
+ - affiliate_tags
138
+ - affiliate_tiers
139
+ - billing_cycles
140
+ - blacklist_reasons
141
+ - cap_intervals
142
+ - cap_types
143
+ - countries
144
+ - currencies
145
+ - departments
146
+ - exchange_rates
147
+ - get_api_key
148
+ - inactive_reasons
149
+ - languages
150
+ - offer_statuses
151
+ - offer_types
152
+ - payment_settings
153
+ - payment_types
154
+ - price_formats
155
+ - roles
156
+ - tracking_domains
157
+ - verticals
158
+ reports:
159
+ - advertiser_summary
160
+ - affiliate_summary
161
+ - campaign_summary
162
+ - creative_summary
163
+ - caps
164
+ - clicks
165
+ - conversion_changes
166
+ - conversions
167
+ - daily_summary_export
168
+ - leads_by_affiliate_export
169
+ - leads_by_buyer
170
+ - login_export
171
+ - offer_summary
172
+ - traffic_export
173
+ signup:
174
+ - get_media_types
175
+ - get_price_formats
176
+ - get_traffic_types
177
+ - get_vertical_categories
178
+ track:
179
+ - accepted_dispositions
180
+ - conversion_dispositions
181
+ - decrypt_affiliate_link
182
+ - rejected_dispositions
183
+ affiliate:
184
+ reports:
185
+ - bills
186
+ offers:
187
+ - offer_feed
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'logger'
2
3
  require 'nokogiri'
3
4
  require 'saxerator'
@@ -23,6 +24,6 @@ require 'soapy_cake/admin_track'
23
24
  require 'soapy_cake/affiliate'
24
25
 
25
26
  module SoapyCake
26
- API_VERSIONS = YAML.load(File.read(File.expand_path('../../api_versions.yml', __FILE__)))
27
+ API_CONFIG = YAML.load(File.read(File.expand_path('../../api.yml', __FILE__)))
27
28
  NET_TIMEOUT = 600
28
29
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SoapyCake
2
3
  # rubocop:disable Metrics/ClassLength
3
4
  class Admin < Client
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SoapyCake
2
3
  # rubocop:disable Metrics/ClassLength
3
4
  class AdminAddedit < Client
@@ -114,7 +115,7 @@ module SoapyCake
114
115
  opts = opts.dup
115
116
  redirects = opts.delete(:redirects)
116
117
  unless redirects.is_a?(Hash) && redirects.keys.count > 0
117
- fail Error, "Parameter 'redirects' must be a COUNTRY=>REDIRECT_OFFER_CONTRACT_ID hash!"
118
+ raise Error, "Parameter 'redirects' must be a COUNTRY=>REDIRECT_OFFER_CONTRACT_ID hash!"
118
119
  end
119
120
 
120
121
  opts[:countries] = redirects.keys.join(',')
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SoapyCake
2
3
  class AdminBatched
3
4
  ALLOWED_METHODS = %i(
@@ -20,7 +21,7 @@ module SoapyCake
20
21
 
21
22
  def initialize(admin, method, opts, limit)
22
23
  if opts.key?(:row_limit) || opts.key?(:start_at_row)
23
- fail Error, 'Cannot set row_limit/start_at_row in batched mode!'
24
+ raise Error, 'Cannot set row_limit/start_at_row in batched mode!'
24
25
  end
25
26
 
26
27
  @admin = admin
@@ -60,7 +61,7 @@ module SoapyCake
60
61
  end
61
62
 
62
63
  def method_missing(name, method_opts = {}, limit = nil)
63
- fail Error, "Invalid method #{name}" unless ALLOWED_METHODS.include?(name)
64
+ raise Error, "Invalid method #{name}" unless ALLOWED_METHODS.include?(name)
64
65
 
65
66
  BatchedRequest.new(admin, name, method_opts, limit).to_enum
66
67
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SoapyCake
2
3
  class AdminTrack < Client
3
4
  include Helper
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SoapyCake
2
3
  class Affiliate < Client
3
4
  def bills(opts = {})
@@ -1,18 +1,15 @@
1
+ # frozen_string_literal: true
1
2
  module SoapyCake
2
3
  class Client
3
4
  HEADERS = { 'Content-Type' => 'application/soap+xml;charset=UTF-8' }.freeze
4
5
 
5
6
  def initialize(opts = {})
6
- @domain = opts.fetch(:domain, ENV['CAKE_DOMAIN']) || fail(Error, 'Cake domain missing')
7
- @api_key = opts.fetch(:api_key, ENV['CAKE_API_KEY']) || fail(Error, 'Cake API key missing')
8
- @retry_count = opts.fetch(:retry_count, ENV['CAKE_RETRY_COUNT']) || 4
9
-
10
- @time_converter = TimeConverter.new(
11
- opts.fetch(:time_zone, ENV['CAKE_TIME_ZONE']),
12
- opts.fetch(:time_offset, ENV['CAKE_TIME_OFFSET'])
13
- )
14
-
15
7
  @opts = opts
8
+ @domain = fetch_opt(:domain) || raise(Error, 'Cake domain missing')
9
+ @api_key = fetch_opt(:api_key) || raise(Error, 'Cake API key missing')
10
+ @retry_count = fetch_opt(:retry_count, 4)
11
+ @write_enabled = ['yes', true].include?(fetch_opt(:write_enabled))
12
+ @time_converter = TimeConverter.new(fetch_opt(:time_zone), fetch_opt(:time_offset))
16
13
  end
17
14
 
18
15
  def xml_response?
@@ -21,17 +18,14 @@ module SoapyCake
21
18
 
22
19
  protected
23
20
 
24
- attr_reader :domain, :api_key, :time_converter, :opts, :logger, :retry_count
21
+ attr_reader :domain, :api_key, :time_converter, :opts, :logger, :retry_count, :write_enabled
25
22
 
26
23
  def run(request)
24
+ check_write_enabled!(request)
27
25
  request.api_key = api_key
28
26
  request.time_converter = time_converter
29
27
 
30
- Retryable.retryable(
31
- tries: retry_count + 1,
32
- on: [RateLimitError, SocketError],
33
- sleep: -> (n) { 3**n }
34
- ) do
28
+ with_retries do
35
29
  response = Response.new(response_body(request), request.short_response?, time_converter)
36
30
  xml_response? ? response.to_xml : response.to_enum
37
31
  end
@@ -39,6 +33,21 @@ module SoapyCake
39
33
 
40
34
  private
41
35
 
36
+ def fetch_opt(key, fallback = nil)
37
+ opts.fetch(key, ENV.fetch("CAKE_#{key.to_s.upcase}", fallback))
38
+ end
39
+
40
+ def check_write_enabled!(request)
41
+ unless request.read_only? || write_enabled
42
+ raise Error, 'Writes not enabled (pass write_enabled: true or set CAKE_WRITE_ENABLED=yes)'
43
+ end
44
+ end
45
+
46
+ def with_retries(&block)
47
+ opts = { tries: retry_count + 1, on: [RateLimitError, SocketError], sleep: -> (n) { 3**n } }
48
+ Retryable.retryable(opts, &block)
49
+ end
50
+
42
51
  def logger
43
52
  @logger ||= opts[:logger] || (defined?(::Rails) && ::Rails.logger)
44
53
  end
@@ -51,12 +60,9 @@ module SoapyCake
51
60
  logger.info("soapy_cake:request #{request}") if logger
52
61
 
53
62
  url = "https://#{domain}#{request.path}"
54
- http_response = HTTParty.post(url, headers: HEADERS, body: request.xml, timeout: NET_TIMEOUT)
55
-
56
- fail RequestFailed, "Request failed with HTTP #{http_response.code}: " \
57
- "#{http_response.body}" unless http_response.success?
58
-
59
- http_response
63
+ HTTParty.post(url, headers: HEADERS, body: request.xml, timeout: NET_TIMEOUT).tap do |res|
64
+ raise RequestFailed, "Request failed with HTTP #{res.code}: #{res.body}" unless res.success?
65
+ end
60
66
  end
61
67
  end
62
68
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SoapyCake
2
3
  module Const
3
4
  # The ID mapping in the API docs is wrong, these values are taken from the UI.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SoapyCake
2
3
  class Error < RuntimeError; end
3
4
  class RequestFailed < Error; end
@@ -15,20 +15,20 @@ module SoapyCake
15
15
  end
16
16
 
17
17
  def validate_id(opts, key)
18
- fail Error, "Parameter '#{key}' must be > 0!" if opts[key].to_i < 1
18
+ raise Error, "Parameter '#{key}' must be > 0!" if opts[key].to_i < 1
19
19
  end
20
20
 
21
21
  def require_params(opts, params)
22
22
  params.each do |param|
23
- fail Error, "Parameter '#{param}' missing!" unless opts.key?(param)
23
+ raise Error, "Parameter '#{param}' missing!" unless opts.key?(param)
24
24
  end
25
25
  end
26
26
 
27
27
  def translate_booleans(opts)
28
28
  opts.transform_values do |v|
29
29
  case v
30
- when true then 'on'.freeze
31
- when false then 'off'.freeze
30
+ when true then 'on'
31
+ when false then 'off'
32
32
  else v
33
33
  end
34
34
  end
@@ -45,7 +45,7 @@ module SoapyCake
45
45
 
46
46
  def const_lookup(type, key)
47
47
  Const::CONSTS[type].fetch(key) do
48
- fail ArgumentError, "#{key} is not a valid value for #{type}"
48
+ raise ArgumentError, "#{key} is not a valid value for #{type}"
49
49
  end
50
50
  end
51
51
 
@@ -38,6 +38,10 @@ module SoapyCake
38
38
  "#{role}:#{service}:#{method}:#{version} #{opts.to_json}"
39
39
  end
40
40
 
41
+ def read_only?
42
+ (API_CONFIG.dig('read_only', role, service) || []).include?(method)
43
+ end
44
+
41
45
  private
42
46
 
43
47
  def api_path
@@ -61,17 +65,16 @@ module SoapyCake
61
65
  def format_param(key, value)
62
66
  return time_converter.to_cake(value) if DATE_CLASSES.include?(value.class)
63
67
 
64
- if key.to_s.end_with?('_date'.freeze)
65
- fail Error, "You need to use a Time/DateTime/Date object for '#{key}'"
68
+ if key.to_s.end_with?('_date')
69
+ raise Error, "You need to use a Time/DateTime/Date object for '#{key}'"
66
70
  end
67
71
 
68
72
  value
69
73
  end
70
74
 
71
75
  def version
72
- API_VERSIONS[role][service][method] || fail
73
- rescue
74
- raise(Error, "Unknown API call #{role}::#{service}::#{method}")
76
+ API_CONFIG.dig('versions', role, service, method) ||
77
+ raise(Error, "Unknown API call #{role}::#{service}::#{method}")
75
78
  end
76
79
  end
77
80
  end
@@ -63,13 +63,13 @@ module SoapyCake
63
63
 
64
64
  def error_check_fault!
65
65
  fault = sax.for_tag(:fault).first
66
- fail RequestFailed, fault[:reason][:text] if fault
66
+ raise RequestFailed, fault[:reason][:text] if fault
67
67
  end
68
68
 
69
69
  def error_check_success!
70
- return if sax.for_tag(:success).first == 'true'.freeze
71
- fail RateLimitError if error_message == 'Restricted'.freeze
72
- fail RequestFailed, error_message
70
+ return if sax.for_tag(:success).first == 'true'
71
+ raise RateLimitError if error_message == 'Restricted'
72
+ raise RequestFailed, error_message
73
73
  end
74
74
 
75
75
  def error_check_special_case?
@@ -27,11 +27,11 @@ module SoapyCake
27
27
  attr_reader :time_converter
28
28
 
29
29
  def false?
30
- value == 'false'.freeze
30
+ value == 'false'
31
31
  end
32
32
 
33
33
  def true?
34
- value == 'true'.freeze
34
+ value == 'true'
35
35
  end
36
36
 
37
37
  def date?
@@ -39,7 +39,7 @@ module SoapyCake
39
39
  end
40
40
 
41
41
  def id?
42
- key.end_with?('_id'.freeze)
42
+ key.end_with?('_id')
43
43
  end
44
44
 
45
45
  def string_id?
@@ -52,7 +52,7 @@ module SoapyCake
52
52
 
53
53
  def parse_int
54
54
  unless value.nil? || numeric?
55
- fail Error, "'#{key}' contains non-digit chars but was to be parsed as an integer id"
55
+ raise Error, "'#{key}' contains non-digit chars but was to be parsed as an integer id"
56
56
  end
57
57
  value.to_i
58
58
  end
@@ -9,13 +9,13 @@ module SoapyCake
9
9
  time_zone = format('Etc/GMT%+d', -time_offset.to_i)
10
10
  end
11
11
 
12
- fail Error, 'Cake time zone missing' if time_zone.blank?
12
+ raise Error, 'Cake time zone missing' if time_zone.blank?
13
13
  @zone = ActiveSupport::TimeZone[time_zone]
14
14
  end
15
15
 
16
16
  def to_cake(date)
17
17
  date = date.to_datetime if date.is_a?(Date)
18
- date.in_time_zone(zone).strftime('%Y-%m-%dT%H:%M:%S'.freeze)
18
+ date.in_time_zone(zone).strftime('%Y-%m-%dT%H:%M:%S')
19
19
  end
20
20
 
21
21
  def from_cake(value)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module SoapyCake
3
- VERSION = '1.21.0'.freeze
3
+ VERSION = '1.22.0'
4
4
  end
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'soapy_cake/version'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::AdminAddedit do
2
3
  around { |example| Timecop.freeze(Time.utc(2015, 2, 17, 12), &example) }
3
4
 
@@ -37,6 +38,21 @@ RSpec.describe SoapyCake::AdminAddedit do
37
38
  end
38
39
 
39
40
  describe 'offers' do
41
+ let(:update_params) do
42
+ {
43
+ offer_id: offer_id,
44
+ advertiser_id: advertiser_id,
45
+ vertical_id: vertical_id,
46
+ postback_url_ms_delay: 50,
47
+ offer_contract_hidden: false,
48
+ price_format_id: :cpa,
49
+ received: 2.0,
50
+ received_percentage: false,
51
+ payout: 1.5,
52
+ tags: ''
53
+ }
54
+ end
55
+
40
56
  it 'creates an offer', :vcr do
41
57
  result = subject.add_offer(
42
58
  hidden: false,
@@ -86,20 +102,7 @@ RSpec.describe SoapyCake::AdminAddedit do
86
102
  end
87
103
 
88
104
  it 'updates an offer', :vcr do
89
- result = subject.edit_offer(
90
- offer_id: offer_id,
91
-
92
- advertiser_id: advertiser_id,
93
- vertical_id: vertical_id,
94
- postback_url_ms_delay: 50,
95
- offer_contract_hidden: false,
96
- price_format_id: :cpa,
97
- received: 2.0,
98
- received_percentage: false,
99
- payout: 1.5,
100
- tags: ''
101
- )
102
-
105
+ result = subject.edit_offer(update_params)
103
106
  expect(result).to include(offer_id: offer_id)
104
107
  end
105
108
 
@@ -115,6 +118,19 @@ RSpec.describe SoapyCake::AdminAddedit do
115
118
  subject.edit_offer(offer_id: -1)
116
119
  end.to raise_error(SoapyCake::Error, "Parameter 'offer_id' must be > 0!")
117
120
  end
121
+
122
+ context 'when writes not enabled' do
123
+ before do
124
+ allow(ENV).to receive(:fetch).and_call_original
125
+ allow(ENV).to receive(:fetch).with('CAKE_WRITE_ENABLED', nil).and_return('no')
126
+ end
127
+
128
+ it 'fails with error' do
129
+ expect do
130
+ subject.edit_offer(update_params)
131
+ end.to raise_error(SoapyCake::Error, /Writes not enabled/)
132
+ end
133
+ end
118
134
  end
119
135
  end
120
136
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::Admin do
2
3
  around { |example| Timecop.freeze(Time.utc(2015, 6, 15, 12), &example) }
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  RSpec.describe SoapyCake::AdminTrack do
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::AdminAddedit do
2
3
  before do
3
- allow_any_instance_of(SoapyCake::Client).to receive(:run).and_return({})
4
+ allow_any_instance_of(SoapyCake::Client) # rubocop:disable RSpec/AnyInstance
5
+ .to receive(:run).and_return({})
4
6
  end
5
7
 
6
8
  describe '#edit_offer' do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::AdminBatched do
2
3
  let(:admin) { double('admin', xml_response?: false) }
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::Admin do
2
3
  let(:opts) { nil }
3
4
  let(:cake_opts) { opts }
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  RSpec.describe SoapyCake::AdminTrack do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::Affiliate do
2
3
  let(:affiliate_id) { 42 }
3
4
  let(:opts) { { a: 1 } }
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::Request do
2
3
  it 'raises if there is no api version stored' do
3
4
  expect do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::Response do
2
3
  let(:xml) do
3
4
  <<-EOD
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::ResponseValue do
2
3
  let(:time_converter) { double('date converter') }
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.describe SoapyCake::TimeConverter do
2
3
  subject { described_class.new('Europe/Berlin') }
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  if ENV['CODECLIMATE_REPO_TOKEN']
2
3
  require 'codeclimate-test-reporter'
3
4
  CodeClimate::TestReporter.start
@@ -42,6 +43,7 @@ end
42
43
  ENV['CAKE_API_KEY'] = 'cake-api-key' if ENV['CAKE_API_KEY'].blank?
43
44
  ENV['CAKE_DOMAIN'] = 'cake-partner-domain.com' if ENV['CAKE_DOMAIN'].blank?
44
45
  ENV['CAKE_TIME_ZONE'] = 'Europe/Berlin' if ENV['CAKE_TIME_ZONE'].blank?
46
+ ENV['CAKE_WRITE_ENABLED'] = 'yes' if ENV['CAKE_WRITE_ENABLED'].blank?
45
47
 
46
48
  VCR.configure do |c|
47
49
  c.configure_rspec_metadata!
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.shared_examples_for 'a cake admin method' do
2
3
  let(:request) { double('request') }
3
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: soapy_cake
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.21.0
4
+ version: 1.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ad2games GmbH
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-25 00:00:00.000000000 Z
11
+ date: 2016-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -192,7 +192,7 @@ files:
192
192
  - LICENSE.txt
193
193
  - README.md
194
194
  - Rakefile
195
- - api_versions.yml
195
+ - api.yml
196
196
  - circle.yml
197
197
  - lib/soapy_cake.rb
198
198
  - lib/soapy_cake/admin.rb
@@ -1,113 +0,0 @@
1
- ---
2
- admin:
3
- accounting:
4
- mark_affiliate_bill_as_received: 1
5
- export_advertiser_bills: 1
6
- export_affiliate_bills: 1
7
- mark_affiliate_bill_as_paid: 1
8
- add:
9
- advertiser_credit: 1
10
- creative: 1
11
- manual_credit: 1
12
- addedit:
13
- advertiser: 1
14
- advertiser_credit_limit: 1
15
- affiliate: 2
16
- apply_suppression_list_to_offer: 1
17
- blacklist: 1
18
- campaign: 3
19
- caps: 1
20
- contact: 2
21
- creative: 1
22
- creative_files: 1
23
- exchange_rates: 1
24
- geo_targets: 2
25
- offer: 5
26
- offer_contract: 1
27
- offer_tiers: 1
28
- remove_blacklist: 1
29
- suppresion_list: 1
30
- vertical: 1
31
- auth:
32
- login: 2
33
- doc:
34
- posting_doc: 1
35
- edit:
36
- buyer: 1
37
- export:
38
- advertisers: 5
39
- affiliate_referrals: 1
40
- affiliates: 5
41
- blacklists: 1
42
- buyer_contracts: 1
43
- buyers: 1
44
- campaigns: 6
45
- creatives: 3
46
- offers: 5
47
- rules_targets: 3
48
- schedules: 1
49
- get:
50
- account_statuses: 1
51
- advertisers: 1
52
- affiliate_tags: 1
53
- affiliate_tiers: 1
54
- billing_cycles: 1
55
- blacklist_reasons: 1
56
- cap_intervals: 1
57
- cap_types: 1
58
- countries: 1
59
- currencies: 1
60
- departments: 1
61
- exchange_rates: 1
62
- get_api_key: 1
63
- inactive_reasons: 1
64
- languages: 1
65
- offer_statuses: 1
66
- offer_types: 1
67
- payment_settings: 1
68
- payment_types: 1
69
- price_formats: 1
70
- roles: 1
71
- tracking_domains: 1
72
- verticals: 2
73
- reports:
74
- advertiser_summary: 2
75
- affiliate_summary: 2
76
- campaign_summary: 2
77
- creative_summary: 2
78
- caps: 4
79
- clicks: 7
80
- conversion_changes: 10
81
- conversions: 11
82
- daily_summary_export: 1
83
- leads_by_affiliate_export: 1
84
- leads_by_buyer: 4
85
- login_export: 1
86
- offer_summary: 2
87
- traffic_export: 1
88
- signup:
89
- advertiser: 1
90
- affiliate: 4
91
- get_media_types: 1
92
- get_price_formats: 1
93
- get_traffic_types: 1
94
- get_vertical_categories: 1
95
- track:
96
- accepted_dispositions: 1
97
- conversion_dispositions: 2
98
- decrypt_affiliate_link: 1
99
- mass_conversion_adjustment: 2
100
- # Version 2 returns an error about an invalid action, so using version 1
101
- mass_conversion_insert: 1
102
- rejected_dispositions: 1
103
- update_conversion: 4
104
- update_conversion_disposition: 2
105
- update_conversion_price: 2
106
- update_conversion_revenue: 1
107
- update_lead_price: 2
108
- update_sale_revenue: 1
109
- affiliate:
110
- reports:
111
- bills: 3
112
- offers:
113
- offer_feed: 4