soapy_cake 1.21.0 → 1.22.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
  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