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 +4 -4
- data/Gemfile +1 -0
- data/Rakefile +1 -0
- data/api.yml +187 -0
- data/lib/soapy_cake.rb +2 -1
- data/lib/soapy_cake/admin.rb +1 -0
- data/lib/soapy_cake/admin_addedit.rb +2 -1
- data/lib/soapy_cake/admin_batched.rb +3 -2
- data/lib/soapy_cake/admin_track.rb +1 -0
- data/lib/soapy_cake/affiliate.rb +1 -0
- data/lib/soapy_cake/client.rb +27 -21
- data/lib/soapy_cake/const.rb +1 -0
- data/lib/soapy_cake/error.rb +1 -0
- data/lib/soapy_cake/helper.rb +5 -5
- data/lib/soapy_cake/request.rb +8 -5
- data/lib/soapy_cake/response.rb +4 -4
- data/lib/soapy_cake/response_value.rb +4 -4
- data/lib/soapy_cake/time_converter.rb +2 -2
- data/lib/soapy_cake/version.rb +1 -1
- data/soapy_cake.gemspec +1 -0
- data/spec/integration/soapy_cake/admin_addedit_spec.rb +30 -14
- data/spec/integration/soapy_cake/admin_spec.rb +1 -0
- data/spec/integration/soapy_cake/admin_track_spec.rb +1 -0
- data/spec/lib/soapy_cake/admin_addedit_spec.rb +3 -1
- data/spec/lib/soapy_cake/admin_batched_spec.rb +1 -0
- data/spec/lib/soapy_cake/admin_spec.rb +1 -0
- data/spec/lib/soapy_cake/admin_track_spec.rb +1 -0
- data/spec/lib/soapy_cake/affiliate_spec.rb +1 -0
- data/spec/lib/soapy_cake/request_spec.rb +1 -0
- data/spec/lib/soapy_cake/response_spec.rb +1 -0
- data/spec/lib/soapy_cake/response_value_spec.rb +1 -0
- data/spec/lib/soapy_cake/time_converter_spec.rb +1 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/admin_method_example.rb +1 -0
- metadata +3 -3
- data/api_versions.yml +0 -113
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56f71b18325d9c37c28fa1eb52a36785b29cbde1
|
4
|
+
data.tar.gz: 489dfd14ad0e7fe93571ae955544830dced450c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea22778f46a5c0097f0b182c1f84cff5c509694011dabde1c2794f505a713fa5abae06efe7009c479e81fb4e90cfef16962bb2ea181da0f2dbb4df98a60331d2
|
7
|
+
data.tar.gz: 0ce89c5f006bc80e3daafd7a46cecba01ced9fef6a61afc33a617dd2d820b68b67be0c7e6990ac35a1e829f078dc04750be186ede15c2fbbbf67a554824d17d8
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
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
|
data/lib/soapy_cake.rb
CHANGED
@@ -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
|
-
|
27
|
+
API_CONFIG = YAML.load(File.read(File.expand_path('../../api.yml', __FILE__)))
|
27
28
|
NET_TIMEOUT = 600
|
28
29
|
end
|
data/lib/soapy_cake/admin.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/soapy_cake/affiliate.rb
CHANGED
data/lib/soapy_cake/client.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
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
|
data/lib/soapy_cake/const.rb
CHANGED
data/lib/soapy_cake/error.rb
CHANGED
data/lib/soapy_cake/helper.rb
CHANGED
@@ -15,20 +15,20 @@ module SoapyCake
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def validate_id(opts, key)
|
18
|
-
|
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
|
-
|
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'
|
31
|
-
when false then 'off'
|
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
|
-
|
48
|
+
raise ArgumentError, "#{key} is not a valid value for #{type}"
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
data/lib/soapy_cake/request.rb
CHANGED
@@ -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'
|
65
|
-
|
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
|
-
|
73
|
-
|
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
|
data/lib/soapy_cake/response.rb
CHANGED
@@ -63,13 +63,13 @@ module SoapyCake
|
|
63
63
|
|
64
64
|
def error_check_fault!
|
65
65
|
fault = sax.for_tag(:fault).first
|
66
|
-
|
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'
|
71
|
-
|
72
|
-
|
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'
|
30
|
+
value == 'false'
|
31
31
|
end
|
32
32
|
|
33
33
|
def true?
|
34
|
-
value == 'true'
|
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'
|
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
|
-
|
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
|
-
|
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'
|
18
|
+
date.in_time_zone(zone).strftime('%Y-%m-%dT%H:%M:%S')
|
19
19
|
end
|
20
20
|
|
21
21
|
def from_cake(value)
|
data/lib/soapy_cake/version.rb
CHANGED
data/soapy_cake.gemspec
CHANGED
@@ -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,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)
|
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
|
data/spec/spec_helper.rb
CHANGED
@@ -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!
|
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.
|
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-
|
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
|
-
-
|
195
|
+
- api.yml
|
196
196
|
- circle.yml
|
197
197
|
- lib/soapy_cake.rb
|
198
198
|
- lib/soapy_cake/admin.rb
|
data/api_versions.yml
DELETED
@@ -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
|