soapy_cake 2.2.4 → 2.3.1

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 (29) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +62 -0
  3. data/.ruby-version +1 -1
  4. data/Gemfile +2 -2
  5. data/README.md +2 -3
  6. data/api.yml +1 -0
  7. data/lib/soapy_cake.rb +1 -1
  8. data/lib/soapy_cake/admin_addedit.rb +1 -0
  9. data/lib/soapy_cake/admin_track.rb +2 -4
  10. data/lib/soapy_cake/campaigns.rb +9 -8
  11. data/lib/soapy_cake/client.rb +63 -37
  12. data/lib/soapy_cake/modification_type.rb +4 -1
  13. data/lib/soapy_cake/response.rb +2 -0
  14. data/lib/soapy_cake/response_value.rb +1 -0
  15. data/lib/soapy_cake/time_converter.rb +1 -16
  16. data/lib/soapy_cake/version.rb +1 -1
  17. data/soapy_cake.gemspec +1 -1
  18. data/spec/fixtures/vcr_cassettes/SoapyCake_AdminTrack/_mass_conversion_insert/inserts_conversions.yml +14 -6
  19. data/spec/fixtures/vcr_cassettes/SoapyCake_AdminTrack/_update_conversion/updates_a_conversion.yml +29 -15
  20. data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_patch/different_pre-existing_values/does_not_change_anything_unintentionally_attribute_set_0_.yml +0 -1
  21. data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_patch/different_pre-existing_values/does_not_change_anything_unintentionally_attribute_set_1_.yml +0 -1
  22. data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_patch/updates_a_campaign.yml +0 -2
  23. data/spec/integration/soapy_cake/admin_spec.rb +10 -5
  24. data/spec/lib/soapy_cake/admin_addedit_spec.rb +58 -46
  25. data/spec/lib/soapy_cake/admin_track_spec.rb +1 -1
  26. data/spec/lib/soapy_cake/time_converter_spec.rb +0 -13
  27. metadata +8 -9
  28. data/circle.yml +0 -8
  29. data/lib/soapy_cake/request_mass_conversion_insert.rb +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 70c84bead32dad291a2969cf47b93f30e7ca08ea
4
- data.tar.gz: 71bf3ac75e66d776971df47f70e6d955f3034407
2
+ SHA256:
3
+ metadata.gz: 067f6e7655ca70f82bdb56092d19dcfbb0f41879077ede785b6490ee40ba0192
4
+ data.tar.gz: 945cce14ca15a79590bef7b1bef2a636288da4cfb0ba93b6d9f50482ecdc533b
5
5
  SHA512:
6
- metadata.gz: a4ef76954d20b9576ceb510fbcbb015fa750f772ca3719b39bfb41df118b360c0929a8ba1cdf220d89ad6c9685350e23ef0189c35c40f2cfc4513df0d150749b
7
- data.tar.gz: 79dc72b5b081674155311aaa690e56e567dda81024eb86dadcc3dd786ebed07d43f8955404018e3feae36140fa095eef710448ceb5024c69f3ebf750b1377a56
6
+ metadata.gz: bc1c8bbba8cf6b41ca72aeebe6c516b7a915a8a3fb1bead22794e87c600aba8b4e6d8b7c590e0e6c700e3a327f8eb0264b3f0142d837c6b3e13be7dbbffce967
7
+ data.tar.gz: 9ecf1e1d0d996917d3b079b8e74f0bd3db0f5ea67d27d276c78cb8387572045893b01555877aaab17c09e20ce5e7ba0df6a0b8ebfea7152416597160f917b791
@@ -0,0 +1,62 @@
1
+ version: 2
2
+ jobs:
3
+ setup:
4
+ docker: &docker
5
+ - image: circleci/ruby:2.5.1-node
6
+ environment:
7
+ BUNDLE_PATH: vendor/bundle
8
+
9
+ steps:
10
+ - checkout
11
+
12
+ - run:
13
+ name: Check if Ruby versions match
14
+ command: test "$(ruby -v | grep -oP '\d\.\d\.\d')" = "$(cat .ruby-version)"
15
+
16
+ - run:
17
+ name: Install dependencies
18
+ command: bundle install --jobs=4 --retry=3
19
+
20
+ - persist_to_workspace:
21
+ root: .
22
+ paths:
23
+ - .
24
+
25
+ lint:
26
+ docker: *docker
27
+ steps:
28
+ - attach_workspace:
29
+ at: .
30
+
31
+ - run: bundle exec rake rubocop
32
+
33
+ test:
34
+ docker: *docker
35
+ steps:
36
+ - attach_workspace:
37
+ at: .
38
+
39
+ - run:
40
+ name: run tests
41
+ command: |
42
+ mkdir /tmp/test-results
43
+
44
+ bundle exec rspec --format progress \
45
+ --format RspecJunitFormatter \
46
+ --out /tmp/test-results/rspec.xml \
47
+ --format progress
48
+
49
+ - store_test_results:
50
+ path: /tmp/test-results
51
+
52
+ workflows:
53
+ version: 2
54
+ lint-and-test:
55
+ jobs:
56
+ - setup
57
+ - lint:
58
+ requires:
59
+ - setup
60
+ - test:
61
+ requires:
62
+ - setup
@@ -1 +1 @@
1
- 2.4.3
1
+ 2.5.1
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ source 'https://rubygems.org'
5
5
  gemspec
6
6
 
7
7
  group :development, :test do
8
- gem 'codeclimate-test-reporter', require: false
9
- gem 'rubocop-ci', git: 'https://github.com/ad2games/rubocop-ci'
8
+ gem 'rspec_junit_formatter'
9
+ gem 'rubocop-ci', git: 'https://github.com/ComboStrikeHQ/rubocop-ci'
10
10
  gem 'simplecov'
11
11
  end
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # SoapyCake
2
- [![Code Climate](https://codeclimate.com/github/ad2games/soapy_cake.png)](https://codeclimate.com/github/ad2games/soapy_cake)
3
- [![Test Coverage](https://codeclimate.com/github/ad2games/soapy_cake/coverage.png)](https://codeclimate.com/github/ad2games/soapy_cake)
2
+ [![Maintainability](https://api.codeclimate.com/v1/badges/506ccd1a270e86f6b2bb/maintainability)](https://codeclimate.com/github/ad2games/soapy_cake/maintainability)
3
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/506ccd1a270e86f6b2bb/test_coverage)](https://codeclimate.com/github/ad2games/soapy_cake/test_coverage)
4
4
  [![Gem Version](http://img.shields.io/gem/v/soapy_cake.svg)](http://rubygems.org/gems/soapy_cake)
5
- [![Dependency Status](http://img.shields.io/gemnasium/ad2games/soapy_cake.svg)](https://gemnasium.com/ad2games/soapy_cake)
6
5
  [![Circle CI](https://circleci.com/gh/ad2games/soapy_cake.png?style=shield&circle-token=aac691804f58acd8e96db632f8133e3c6155f123)](https://circleci.com/gh/ad2games/soapy_cake)
7
6
 
8
7
  Simple client library for [cake](http://getcake.com).
data/api.yml CHANGED
@@ -102,6 +102,7 @@ versions:
102
102
  rejected_dispositions: 1
103
103
  update_conversion: 4
104
104
  update_conversion_disposition: 2
105
+ update_conversion_events: 6
105
106
  update_conversion_price: 2
106
107
  update_conversion_revenue: 1
107
108
  update_lead_price: 2
@@ -28,6 +28,6 @@ require 'soapy_cake/modification_type'
28
28
  require 'soapy_cake/campaigns'
29
29
 
30
30
  module SoapyCake
31
- API_CONFIG = YAML.safe_load(File.read(File.expand_path('../../api.yml', __FILE__)))
31
+ API_CONFIG = YAML.safe_load(File.read(File.expand_path('../api.yml', __dir__)))
32
32
  NET_TIMEOUT = 600
33
33
  end
@@ -239,6 +239,7 @@ module SoapyCake
239
239
 
240
240
  def apply_tag_opts(opts)
241
241
  return opts unless opts[:tags]
242
+
242
243
  opts = apply_tag_modification_type(opts)
243
244
  opts[:tags] = Array(opts[:tags]).join(',')
244
245
  opts
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'soapy_cake/request_mass_conversion_insert'
4
-
5
3
  module SoapyCake
6
4
  class AdminTrack < Client
7
5
  include Helper
@@ -23,13 +21,13 @@ module SoapyCake
23
21
  campaign_id creative_id total_to_insert
24
22
  ])
25
23
 
26
- run RequestMassConversionInsert.new(:admin, :track, :mass_conversion_insert, opts)
24
+ run Request.new(:admin, :track, :mass_conversion_insert, opts)
27
25
  end
28
26
 
29
27
  def update_conversion(opts)
30
28
  require_params(opts, %i[offer_id payout])
31
29
 
32
- run Request.new(:admin, :track, :update_conversion, CONVERSION_DEFAULTS.merge(opts))
30
+ run Request.new(:admin, :track, :update_conversion_events, CONVERSION_DEFAULTS.merge(opts))
33
31
  end
34
32
 
35
33
  def decrypt_affiliate_link(opts = {})
@@ -8,12 +8,12 @@ module SoapyCake
8
8
  # be in the list.
9
9
  ALL_PARAMS = %i[
10
10
  account_status_id affiliate_id auto_disposition_delay_hours campaign_id
11
- clear_session_on_conversion currency_id display_link_type_id
12
- expiration_date expiration_date_modification_type media_type_id
13
- offer_contract_id offer_id paid paid_redirects paid_upsells payout
14
- payout_update_option pixel_html postback_delay_ms postback_url
15
- redirect_404 redirect_domain redirect_offer_contract_id review test_link
16
- third_party_name unique_key_hash use_offer_contract_payout
11
+ clear_session_on_conversion currency_id expiration_date
12
+ expiration_date_modification_type media_type_id offer_contract_id
13
+ offer_id paid paid_redirects paid_upsells payout payout_update_option
14
+ pixel_html postback_delay_ms postback_url redirect_404 redirect_domain
15
+ redirect_offer_contract_id review test_link third_party_name
16
+ unique_key_hash use_offer_contract_payout
17
17
  ].freeze
18
18
 
19
19
  NO_CHANGE_VALUES = {
@@ -54,13 +54,14 @@ module SoapyCake
54
54
  nil
55
55
  end
56
56
 
57
+ # The default for `display_link_type_id` is "Fallback" in Cake, which
58
+ # doesn't have an ID and, hence, cannot be set via the API. In order to not
59
+ # change it, it has to be absent from the request.
57
60
  def patch(campaign_id, opts = {})
58
61
  campaign = get(campaign_id: campaign_id).first
59
62
  opts = NO_CHANGE_VALUES
60
63
  .merge(
61
64
  affiliate_id: campaign.fetch(:affiliate).fetch(:affiliate_id),
62
- # Only present in production:
63
- display_link_type_id: campaign.dig(:display_link_type, :link_display_type_id) || 1,
64
65
  media_type_id: campaign.fetch(:media_type).fetch(:media_type_id),
65
66
  offer_contract_id: campaign.fetch(:offer_contract).fetch(:offer_contract_id),
66
67
  offer_id: campaign.fetch(:offer).fetch(:offer_id),
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'net/http'
4
+ require 'active_support/tagged_logging'
4
5
 
6
+ # rubocop:disable Metrics/ClassLength
5
7
  module SoapyCake
6
8
  class Client
7
9
  HEADERS = { 'Content-Type' => 'application/soap+xml;charset=UTF-8' }.freeze
@@ -12,7 +14,7 @@ module SoapyCake
12
14
  @api_key = fetch_opt(:api_key) || raise(Error, 'Cake API key missing')
13
15
  @retry_count = fetch_opt(:retry_count, 4)
14
16
  @write_enabled = ['yes', true].include?(fetch_opt(:write_enabled))
15
- @time_converter = TimeConverter.new(fetch_opt(:time_zone), fetch_opt(:time_offset))
17
+ @time_converter = TimeConverter.new(fetch_opt(:time_zone))
16
18
  end
17
19
 
18
20
  def xml_response?
@@ -29,17 +31,15 @@ module SoapyCake
29
31
  request.time_converter = time_converter
30
32
 
31
33
  with_retries do
32
- begin
33
- response = Response.new(response_body(request), request.short_response?, time_converter)
34
- xml_response? ? response.to_xml : response.to_enum
35
- rescue RequestFailed => e
36
- raise RequestFailed.new(
37
- e.message,
38
- request_path: request.path,
39
- request_body: request.xml,
40
- response_body: e.response_body || response.body
41
- )
42
- end
34
+ response = Response.new(response_body(request), request.short_response?, time_converter)
35
+ xml_response? ? response.to_xml : response.to_enum
36
+ rescue RequestFailed => e
37
+ raise RequestFailed.new(
38
+ e.message,
39
+ request_path: request.path,
40
+ request_body: request.xml,
41
+ response_body: e.response_body || response.body
42
+ )
43
43
  end
44
44
  end
45
45
 
@@ -55,6 +55,7 @@ module SoapyCake
55
55
 
56
56
  def check_write_enabled!(request)
57
57
  return if request.read_only? || write_enabled
58
+
58
59
  raise Error, 'Writes not enabled (pass write_enabled: true or set CAKE_WRITE_ENABLED=yes)'
59
60
  end
60
61
 
@@ -63,45 +64,58 @@ module SoapyCake
63
64
  Retryable.retryable(opts, &block)
64
65
  end
65
66
 
66
- def logger
67
- @logger ||= opts[:logger] || (defined?(::Rails) && ::Rails.logger)
68
- end
69
-
70
- def log_curl_command(request)
71
- curl_headers = HEADERS.map { |k, v| "-H \"#{k}: #{v}\"" }.join(' ')
72
- curl_body = request.xml
73
- .tr("\n", '')
74
- .gsub(/>\s*</, '><')
75
- .sub(request.api_key, '{{{ INSERT API KEY }}}')
76
-
77
- logger&.info("curl --data '#{curl_body}' #{curl_headers} https://#{domain}/#{request.path}")
78
- end
79
-
80
67
  def response_body(request)
81
68
  request.opts[:response].presence || http_response(request)
82
69
  end
83
70
 
84
71
  def http_response(request)
85
- logger&.info("soapy_cake:request #{request}")
72
+ response = nil
73
+ logger.tagged('soapy_cake', unique_id) do
74
+ log_request(request)
75
+ response = perform_http_request(http_request(request))
76
+ log_response(response)
77
+ end
86
78
 
87
- log_curl_command(request) if fetch_opt(:log_curl)
79
+ raise_if_unsuccessful(response)
80
+ response.body
81
+ end
88
82
 
89
- http_request = Net::HTTP::Post.new(request.path, HEADERS)
90
- http_request.body = request.xml
91
- response = perform_http_request(http_request)
83
+ def http_request(request)
84
+ http_req = Net::HTTP::Post.new(request.path, HEADERS)
85
+ http_req.body = request.xml
86
+ http_req
87
+ end
92
88
 
93
- unless response.is_a?(Net::HTTPSuccess)
94
- raise RequestFailed.new(
95
- "Request failed with HTTP #{response.code}",
96
- response_body: response.body
89
+ def unique_id
90
+ SecureRandom.hex(4)
91
+ end
92
+
93
+ def log_request(request)
94
+ logger.tagged('request') do
95
+ logger.info(
96
+ request
97
+ .xml
98
+ .gsub(/>[\n\s]+</, '><')
99
+ .sub(request.api_key, '[REDACTED]')
97
100
  )
98
101
  end
102
+ end
99
103
 
100
- response.body
104
+ def log_response(response)
105
+ logger.tagged('response', response.code) do
106
+ logger.info(response.body)
107
+ end
108
+ end
109
+
110
+ def logger
111
+ @logger ||= ActiveSupport::TaggedLogging.new(
112
+ opts[:logger] || (defined?(::Rails) && ::Rails.logger) || Logger.new('/dev/null')
113
+ )
101
114
  end
102
115
 
103
116
  def perform_http_request(http_request)
104
- Net::HTTP.start(
117
+ t0 = Time.now
118
+ response = Net::HTTP.start(
105
119
  domain,
106
120
  use_ssl: true,
107
121
  open_timeout: NET_TIMEOUT,
@@ -109,6 +123,18 @@ module SoapyCake
109
123
  ) do |http|
110
124
  http.request(http_request)
111
125
  end
126
+ logger.info("took: #{(Time.now - t0).round(2)} s")
127
+ response
128
+ end
129
+
130
+ def raise_if_unsuccessful(response)
131
+ return if response.is_a?(Net::HTTPSuccess)
132
+
133
+ raise RequestFailed.new(
134
+ "Request failed with HTTP #{response.code}",
135
+ response_body: response.body
136
+ )
112
137
  end
113
138
  end
114
139
  end
140
+ # rubocop:enable Metrics/ClassLength
@@ -37,8 +37,11 @@ module SoapyCake
37
37
 
38
38
  def validate_input(input_opts)
39
39
  return unless input_opts[key].nil? && input_opts[modification_type_key] == CHANGE
40
- raise InvalidInput,
40
+
41
+ raise(
42
+ InvalidInput,
41
43
  "`#{modification_type_key}` was '#{CHANGE}', but no `#{key}` was provided to change it to"
44
+ )
42
45
  end
43
46
 
44
47
  InvalidInput = Class.new(StandardError)
@@ -59,6 +59,7 @@ module SoapyCake
59
59
 
60
60
  error_check_fault!
61
61
  return if error_check_special_case?
62
+
62
63
  error_check_success!
63
64
  end
64
65
 
@@ -70,6 +71,7 @@ module SoapyCake
70
71
  def error_check_success!
71
72
  return if sax.for_tag(:success).first == 'true'
72
73
  raise RateLimitError if error_message == 'Restricted'
74
+
73
75
  raise RequestFailed, error_message
74
76
  end
75
77
 
@@ -55,6 +55,7 @@ module SoapyCake
55
55
  unless value.nil? || numeric?
56
56
  raise Error, "'#{key}' contains non-digit chars but was to be parsed as an integer id"
57
57
  end
58
+
58
59
  value.to_i
59
60
  end
60
61
  end
@@ -2,15 +2,7 @@
2
2
 
3
3
  module SoapyCake
4
4
  class TimeConverter
5
- def initialize(time_zone, time_offset = nil)
6
- if time_offset
7
- self.class.print_deprecation_warning
8
-
9
- # Etc/GMT time zones have their sign reversed
10
- time_zone = format('Etc/GMT%+d', -time_offset.to_i)
11
- end
12
-
13
- raise Error, 'Cake time zone missing' if time_zone.blank?
5
+ def initialize(time_zone)
14
6
  @zone = ActiveSupport::TimeZone[time_zone]
15
7
  end
16
8
 
@@ -23,13 +15,6 @@ module SoapyCake
23
15
  zone.parse(value).utc
24
16
  end
25
17
 
26
- def self.print_deprecation_warning
27
- return if @deprecation_warning_printed
28
- @deprecation_warning_printed = true
29
-
30
- STDERR.puts 'SoapyCake - DEPRECATED: Please use time_zone instead of time_offset.'
31
- end
32
-
33
18
  private
34
19
 
35
20
  attr_reader :zone
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SoapyCake
4
- VERSION = '2.2.4'
4
+ VERSION = '2.3.1'
5
5
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('../lib', __FILE__)
3
+ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'soapy_cake/version'
6
6
 
@@ -4,10 +4,10 @@ http_interactions:
4
4
  method: post
5
5
  uri: https://cake-partner-domain.com/api/2/track.asmx
6
6
  body:
7
- encoding: ASCII-8BIT
7
+ encoding: UTF-8
8
8
  string: |
9
9
  <?xml version="1.0"?>
10
- <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:cake="http://cakemarketing.com/api/1/">
10
+ <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:cake="http://cakemarketing.com/api/2/">
11
11
  <env:Header/>
12
12
  <env:Body>
13
13
  <cake:MassConversionInsert>
@@ -39,6 +39,14 @@ http_interactions:
39
39
  code: 200
40
40
  message: OK
41
41
  headers:
42
+ Access-Control-Allow-Credentials:
43
+ - 'true'
44
+ Access-Control-Allow-Headers:
45
+ - Origin, X-Requested-With, Content-Type, Accept
46
+ Access-Control-Allow-Methods:
47
+ - POST,GET,OPTIONS,PUT,DELETE
48
+ Access-Control-Max-Age:
49
+ - '1728000'
42
50
  Cache-Control:
43
51
  - private, max-age=0
44
52
  Content-Length:
@@ -46,7 +54,7 @@ http_interactions:
46
54
  Content-Type:
47
55
  - application/soap+xml; charset=utf-8
48
56
  Date:
49
- - Mon, 24 Jul 2017 19:42:39 GMT
57
+ - Thu, 30 Aug 2018 15:39:26 GMT
50
58
  X-Aspnet-Version:
51
59
  - 4.0.30319
52
60
  X-Powered-By:
@@ -57,8 +65,8 @@ http_interactions:
57
65
  encoding: UTF-8
58
66
  string: <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
59
67
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><MassConversionInsertResponse
60
- xmlns="http://cakemarketing.com/api/1/"><MassConversionInsertResult><success>true</success><message>Conversions
68
+ xmlns="http://cakemarketing.com/api/2/"><MassConversionInsertResult><success>true</success><message>Conversions
61
69
  Inserted</message></MassConversionInsertResult></MassConversionInsertResponse></soap:Body></soap:Envelope>
62
70
  http_version:
63
- recorded_at: Mon, 24 Jul 2017 19:42:40 GMT
64
- recorded_with: VCR 3.0.3
71
+ recorded_at: Thu, 30 Aug 2018 15:39:27 GMT
72
+ recorded_with: VCR 4.0.0
@@ -2,15 +2,15 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: post
5
- uri: https://cake-partner-domain.com/api/4/track.asmx
5
+ uri: https://cake-partner-domain.com/api/6/track.asmx
6
6
  body:
7
7
  encoding: UTF-8
8
8
  string: |
9
9
  <?xml version="1.0"?>
10
- <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:cake="http://cakemarketing.com/api/4/">
10
+ <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:cake="http://cakemarketing.com/api/6/">
11
11
  <env:Header/>
12
12
  <env:Body>
13
- <cake:UpdateConversion>
13
+ <cake:UpdateConversionEvents>
14
14
  <cake:api_key>cake-api-key</cake:api_key>
15
15
  <cake:add_to_existing_payout>false</cake:add_to_existing_payout>
16
16
  <cake:received_option>total_revenue</cake:received_option>
@@ -23,37 +23,51 @@ http_interactions:
23
23
  <cake:conversion_id>145211</cake:conversion_id>
24
24
  <cake:offer_id>5032</cake:offer_id>
25
25
  <cake:payout>0.75</cake:payout>
26
- </cake:UpdateConversion>
26
+ </cake:UpdateConversionEvents>
27
27
  </env:Body>
28
28
  </env:Envelope>
29
29
  headers:
30
30
  Content-Type:
31
31
  - application/soap+xml;charset=UTF-8
32
+ Accept-Encoding:
33
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
34
+ Accept:
35
+ - "*/*"
36
+ User-Agent:
37
+ - Ruby
32
38
  response:
33
39
  status:
34
40
  code: 200
35
41
  message: OK
36
42
  headers:
43
+ Access-Control-Allow-Credentials:
44
+ - 'true'
45
+ Access-Control-Allow-Headers:
46
+ - Origin, X-Requested-With, Content-Type, Accept
47
+ Access-Control-Allow-Methods:
48
+ - POST,GET,OPTIONS,PUT,DELETE
49
+ Access-Control-Max-Age:
50
+ - '1728000'
37
51
  Cache-Control:
38
52
  - private, max-age=0
53
+ Content-Length:
54
+ - '470'
39
55
  Content-Type:
40
56
  - application/soap+xml; charset=utf-8
41
- Server:
42
- - Microsoft-IIS/8.5
57
+ Date:
58
+ - Mon, 20 Jan 2020 14:34:11 GMT
43
59
  X-Aspnet-Version:
44
60
  - 4.0.30319
45
61
  X-Powered-By:
46
62
  - ASP.NET
47
- Date:
48
- - Mon, 12 Oct 2015 09:58:20 GMT
49
- Content-Length:
50
- - '446'
63
+ Connection:
64
+ - close
51
65
  body:
52
66
  encoding: UTF-8
53
67
  string: <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
54
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><UpdateConversionResponse
55
- xmlns="http://cakemarketing.com/api/4/"><UpdateConversionResult><success>true</success><message>Conversion
56
- Updated</message></UpdateConversionResult></UpdateConversionResponse></soap:Body></soap:Envelope>
68
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><UpdateConversionEventsResponse
69
+ xmlns="http://cakemarketing.com/api/6/"><UpdateConversionEventsResult><success>true</success><message>Conversion
70
+ Updated</message></UpdateConversionEventsResult></UpdateConversionEventsResponse></soap:Body></soap:Envelope>
57
71
  http_version:
58
- recorded_at: Mon, 12 Oct 2015 09:58:29 GMT
59
- recorded_with: VCR 2.9.3
72
+ recorded_at: Mon, 20 Jan 2020 14:34:12 GMT
73
+ recorded_with: VCR 4.0.0
@@ -252,7 +252,6 @@ http_interactions:
252
252
  <cake:clear_session_on_conversion>no_change</cake:clear_session_on_conversion>
253
253
  <cake:postback_delay_ms>-1</cake:postback_delay_ms>
254
254
  <cake:affiliate_id>9643</cake:affiliate_id>
255
- <cake:display_link_type_id>1</cake:display_link_type_id>
256
255
  <cake:media_type_id>1</cake:media_type_id>
257
256
  <cake:offer_contract_id>10338</cake:offer_contract_id>
258
257
  <cake:offer_id>11390</cake:offer_id>
@@ -254,7 +254,6 @@ http_interactions:
254
254
  <cake:clear_session_on_conversion>no_change</cake:clear_session_on_conversion>
255
255
  <cake:postback_delay_ms>-1</cake:postback_delay_ms>
256
256
  <cake:affiliate_id>9643</cake:affiliate_id>
257
- <cake:display_link_type_id>1</cake:display_link_type_id>
258
257
  <cake:media_type_id>2</cake:media_type_id>
259
258
  <cake:offer_contract_id>10342</cake:offer_contract_id>
260
259
  <cake:offer_id>11390</cake:offer_id>
@@ -101,7 +101,6 @@ http_interactions:
101
101
  <cake:clear_session_on_conversion>no_change</cake:clear_session_on_conversion>
102
102
  <cake:postback_delay_ms>-1</cake:postback_delay_ms>
103
103
  <cake:affiliate_id>9643</cake:affiliate_id>
104
- <cake:display_link_type_id>1</cake:display_link_type_id>
105
104
  <cake:media_type_id>1</cake:media_type_id>
106
105
  <cake:offer_contract_id>10338</cake:offer_contract_id>
107
106
  <cake:offer_id>11390</cake:offer_id>
@@ -326,7 +325,6 @@ http_interactions:
326
325
  <cake:clear_session_on_conversion>no_change</cake:clear_session_on_conversion>
327
326
  <cake:postback_delay_ms>-1</cake:postback_delay_ms>
328
327
  <cake:affiliate_id>9643</cake:affiliate_id>
329
- <cake:display_link_type_id>1</cake:display_link_type_id>
330
328
  <cake:media_type_id>1</cake:media_type_id>
331
329
  <cake:offer_contract_id>10338</cake:offer_contract_id>
332
330
  <cake:offer_id>11390</cake:offer_id>
@@ -3,17 +3,22 @@
3
3
  RSpec.describe SoapyCake::Admin do
4
4
  around { |example| Timecop.freeze(Time.utc(2015, 6, 15, 12), &example) }
5
5
 
6
- let(:logger) { instance_double(Logger) }
7
-
8
- before { allow(logger).to receive(:info) }
6
+ let(:logger) { Logger.new('/dev/null') }
9
7
 
10
8
  subject(:admin) { described_class.new(logger: logger) }
11
9
 
12
10
  it 'returns an affiliate with correct data types', :vcr do
13
- expect(logger).to receive(:info)
14
- .with('soapy_cake:request admin:export:affiliates:5 {"affiliate_id":16027}')
11
+ # rubocop:disable RSpec/AnyInstance
12
+ expect_any_instance_of(Logger).to receive(:info).twice.with(
13
+ a_string_matching(/^<\?xml/)
14
+ )
15
+ expect_any_instance_of(Logger).to receive(:info).with(
16
+ a_string_matching(/took: \d+.\d+ s/)
17
+ )
18
+ # rubocop:enable RSpec/AnyInstance
15
19
 
16
20
  result = admin.affiliates(affiliate_id: 16027)
21
+
17
22
  expect(result.count).to eq(1)
18
23
  expect(result.first).to include(
19
24
  affiliate_id: 16027,
@@ -26,17 +26,23 @@ RSpec.describe SoapyCake::AdminAddedit do
26
26
  end
27
27
 
28
28
  it 'keeps existing tags' do
29
- expect(SoapyCake::Request).to receive(:new)
30
- .with(:admin, :addedit, :offer,
31
- hash_including(tags: 'new-tag', tags_modification_type: 'add'))
29
+ expect(SoapyCake::Request).to receive(:new).with(
30
+ :admin,
31
+ :addedit,
32
+ :offer,
33
+ hash_including(tags: 'new-tag', tags_modification_type: 'add')
34
+ )
32
35
 
33
36
  admin_addedit.edit_offer(offer_params)
34
37
  end
35
38
 
36
39
  it 'allows replacing tags' do
37
- expect(SoapyCake::Request).to receive(:new)
38
- .with(:admin, :addedit, :offer,
39
- hash_including(tags: 'new-tag', tags_modification_type: 'replace'))
40
+ expect(SoapyCake::Request).to receive(:new).with(
41
+ :admin,
42
+ :addedit,
43
+ :offer,
44
+ hash_including(tags: 'new-tag', tags_modification_type: 'replace')
45
+ )
40
46
 
41
47
  admin_addedit.edit_offer(offer_params.merge(tags_replace: true))
42
48
  end
@@ -78,9 +84,12 @@ RSpec.describe SoapyCake::AdminAddedit do
78
84
  end
79
85
 
80
86
  it 'always adds on creation' do
81
- expect(SoapyCake::Request).to receive(:new)
82
- .with(:admin, :addedit, :offer,
83
- hash_including(tags: 'tag', tags_modification_type: 'add'))
87
+ expect(SoapyCake::Request).to receive(:new).with(
88
+ :admin,
89
+ :addedit,
90
+ :offer,
91
+ hash_including(tags: 'tag', tags_modification_type: 'add')
92
+ )
84
93
 
85
94
  admin_addedit.add_offer(offer_params.merge(tags: 'tag', tags_replace: true))
86
95
  end
@@ -96,17 +105,23 @@ RSpec.describe SoapyCake::AdminAddedit do
96
105
  end
97
106
 
98
107
  it 'replaces the existing config by default' do
99
- expect(SoapyCake::Request).to receive(:new)
100
- .with(:admin, :addedit, :geo_targets,
101
- hash_including(add_edit_option: 'replace'))
108
+ expect(SoapyCake::Request).to receive(:new).with(
109
+ :admin,
110
+ :addedit,
111
+ :geo_targets,
112
+ hash_including(add_edit_option: 'replace')
113
+ )
102
114
 
103
115
  admin_addedit.edit_geo_targets(base_opts)
104
116
  end
105
117
 
106
118
  it 'allows to override the add_edit_option' do
107
- expect(SoapyCake::Request).to receive(:new)
108
- .with(:admin, :addedit, :geo_targets,
109
- hash_including(add_edit_option: 'add'))
119
+ expect(SoapyCake::Request).to receive(:new).with(
120
+ :admin,
121
+ :addedit,
122
+ :geo_targets,
123
+ hash_including(add_edit_option: 'add')
124
+ )
110
125
 
111
126
  admin_addedit.edit_geo_targets(base_opts.merge(add_edit_option: 'add'))
112
127
  end
@@ -130,9 +145,12 @@ RSpec.describe SoapyCake::AdminAddedit do
130
145
  end
131
146
 
132
147
  it 'adds geo targets' do
133
- expect(SoapyCake::Request).to receive(:new)
134
- .with(:admin, :addedit, :geo_targets,
135
- hash_including(add_edit_option: 'add'))
148
+ expect(SoapyCake::Request).to receive(:new).with(
149
+ :admin,
150
+ :addedit,
151
+ :geo_targets,
152
+ hash_including(add_edit_option: 'add')
153
+ )
136
154
 
137
155
  admin_addedit.add_geo_targets(base_opts)
138
156
  end
@@ -157,34 +175,28 @@ RSpec.describe SoapyCake::AdminAddedit do
157
175
 
158
176
  context 'when given the right parameters' do
159
177
  it 'creates a creative and adds a file to it' do
160
- expect(SoapyCake::Request)
161
- .to receive(:new)
162
- .with(
163
- :admin,
164
- :addedit,
165
- :creative,
166
- creative_name: 'creative_name',
167
- creative_status_id: 1,
168
- creative_type_id: 3,
169
- height: 0,
170
- notes: '',
171
- offer_link: '',
172
- third_party_name: '',
173
- width: 0,
174
- offer_id: 10
175
- )
176
- .and_call_original
177
-
178
- expect(SoapyCake::Request)
179
- .to receive(:new)
180
- .with(
181
- :admin,
182
- :addedit,
183
- :creative_files,
184
- creative_file_import_url: 'http://www.example.org/image.png',
185
- creative_id: nil
186
- )
187
- .and_call_original
178
+ expect(SoapyCake::Request).to receive(:new).with(
179
+ :admin,
180
+ :addedit,
181
+ :creative,
182
+ creative_name: 'creative_name',
183
+ creative_status_id: 1,
184
+ creative_type_id: 3,
185
+ height: 0,
186
+ notes: '',
187
+ offer_link: '',
188
+ third_party_name: '',
189
+ width: 0,
190
+ offer_id: 10
191
+ ).and_call_original
192
+
193
+ expect(SoapyCake::Request).to receive(:new).with(
194
+ :admin,
195
+ :addedit,
196
+ :creative_files,
197
+ creative_file_import_url: 'http://www.example.org/image.png',
198
+ creative_id: nil
199
+ ).and_call_original
188
200
 
189
201
  admin_addedit.create_creative(
190
202
  offer_id: 10,
@@ -15,7 +15,7 @@ RSpec.describe SoapyCake::AdminTrack do
15
15
 
16
16
  describe '#update_conversion' do
17
17
  let(:service) { :track }
18
- let(:cake_method) { :update_conversion }
18
+ let(:cake_method) { :update_conversion_events }
19
19
  let(:method) { :update_conversion }
20
20
  let(:cake_opts) { described_class::CONVERSION_DEFAULTS.merge(opts) }
21
21
  let(:opts) { { offer_id: 42, payout: 0 } }
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Style/DateTime
4
3
  RSpec.describe SoapyCake::TimeConverter do
5
4
  subject(:time_converter) { described_class.new('Europe/Berlin') }
6
5
 
@@ -26,16 +25,4 @@ RSpec.describe SoapyCake::TimeConverter do
26
25
  .to eq(Time.utc(2015, 6, 11, 12, 53, 40))
27
26
  end
28
27
  end
29
-
30
- context 'legacy mode / CAKE_TIME_OFFSET' do
31
- subject(:time_converter) { described_class.new('Europe/Berlin', 5) }
32
-
33
- it 'works as before (broken, without DST)' do
34
- expect(STDERR).to receive(:puts).with(/Please use time_zone/)
35
-
36
- expect(time_converter.to_cake(DateTime.new(2015, 1, 2, 12, 30))).to eq('2015-01-02T17:30:00')
37
- expect(time_converter.to_cake(DateTime.new(2015, 6, 2, 12, 30))).to eq('2015-06-02T17:30:00')
38
- end
39
- end
40
28
  end
41
- # rubocop:enable Style/DateTime
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: 2.2.4
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ad2games GmbH
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-25 00:00:00.000000000 Z
11
+ date: 2020-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -185,6 +185,7 @@ executables: []
185
185
  extensions: []
186
186
  extra_rdoc_files: []
187
187
  files:
188
+ - ".circleci/config.yml"
188
189
  - ".gitignore"
189
190
  - ".rspec"
190
191
  - ".rubocop_todo.yml"
@@ -194,7 +195,6 @@ files:
194
195
  - README.md
195
196
  - Rakefile
196
197
  - api.yml
197
- - circle.yml
198
198
  - lib/soapy_cake.rb
199
199
  - lib/soapy_cake/admin.rb
200
200
  - lib/soapy_cake/admin_addedit.rb
@@ -208,7 +208,6 @@ files:
208
208
  - lib/soapy_cake/helper.rb
209
209
  - lib/soapy_cake/modification_type.rb
210
210
  - lib/soapy_cake/request.rb
211
- - lib/soapy_cake/request_mass_conversion_insert.rb
212
211
  - lib/soapy_cake/response.rb
213
212
  - lib/soapy_cake/response_value.rb
214
213
  - lib/soapy_cake/time_converter.rb
@@ -273,7 +272,7 @@ homepage: http://ad2games.com
273
272
  licenses:
274
273
  - MIT
275
274
  metadata: {}
276
- post_install_message:
275
+ post_install_message:
277
276
  rdoc_options: []
278
277
  require_paths:
279
278
  - lib
@@ -288,9 +287,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
288
287
  - !ruby/object:Gem::Version
289
288
  version: '0'
290
289
  requirements: []
291
- rubyforge_project:
292
- rubygems_version: 2.6.14
293
- signing_key:
290
+ rubyforge_project:
291
+ rubygems_version: 2.7.6
292
+ signing_key:
294
293
  specification_version: 4
295
294
  summary: Simple client for the CAKE API
296
295
  test_files:
data/circle.yml DELETED
@@ -1,8 +0,0 @@
1
- dependencies:
2
- post:
3
- - bundle update
4
- test:
5
- pre:
6
- - bundle exec rake rubocop
7
- post:
8
- - bundle exec codeclimate-test-reporter
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SoapyCake
4
- class RequestMassConversionInsert < Request
5
- private
6
-
7
- # There is a bug in MassConversionInsert version 2 API in cake,
8
- # in which xmlns is still using version 1.
9
- def xml_namespaces
10
- {
11
- 'xmlns:env' => 'http://www.w3.org/2003/05/soap-envelope',
12
- 'xmlns:cake' => 'http://cakemarketing.com/api/1/'
13
- }
14
- end
15
- end
16
- end