leanplum_api 1.3.1 → 1.3.5

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: eaef8b007ad46754ae7107b22f86db959f8805c9
4
- data.tar.gz: 503030e7e4f4a85640e42aa2e2d60da7911bad5d
3
+ metadata.gz: e3ada1da3173ffd60da9b2abdddbf4901d20d8cd
4
+ data.tar.gz: 56ca6681108d38d0d91aed19701624db0faae812
5
5
  SHA512:
6
- metadata.gz: 3d9b7d5ad103922bf4888953aaad2e5130b98c2136a8b18a0b02ba30e9d55d6d2d041403eddad4799457c51290b42491570a42a9a68bb63315b3843130cf0814
7
- data.tar.gz: dc14c91eb847b399af97a187bed901f948f88a34462539a2489d72fd587c07a885537e3b3b2f34dac4e8bad3dd4795f0a918ccbd0395e3d99bd64046f876efa7
6
+ metadata.gz: f7f0436608323f894b38932da9dd1cd2ebab1aa5f992267fc0c01f871d48e6bdfed8800317dd255907ec6858a18711118e19de9820165d8cc133ff2663030651
7
+ data.tar.gz: f35e6b7a620fb5f4136f3914381f46abcff6931ebda1a5dbeb5efd2a9fcd072c80bde63b2c7a00135413b803af5fc472b006faa20259d8baab7b7f5b29bc9929
data/README.md CHANGED
@@ -27,10 +27,10 @@ LeanplumApi.configure do |config|
27
27
  config.development_key = 'MY_CONTENT_KEY' # Optional; needed for resetting anomalous events
28
28
 
29
29
  # Optional configuration variables
30
- config.log_path = '/log/path' # Defaults to 'log/'
31
- attr_accessor :timeout_seconds # Defaults to 600
32
- config.api_version # Defaults to 1.0.6
33
- attr_accessor :developer_mode # Defaults to false
30
+ config.logger = LeanplumApi::Logger.new('file.log') # Defaults to STDOUT. The gem logger class hides passwords.
31
+ config.timeout_seconds # Defaults to 600
32
+ config.api_version # Defaults to 1.0.6
33
+ config.developer_mode # Defaults to false
34
34
 
35
35
  # S3 export required options
36
36
  config.s3_bucket_name = 'my_bucket'
@@ -75,6 +75,12 @@ api.track_events(event)
75
75
 
76
76
  # You can also track events and user attributes at the same time
77
77
  api.track_multi(event, attribute_hash)
78
+
79
+ # If your event is sufficiently far in the past, leanplum will mark your user as "Anomalous"
80
+ # To force a reset of this flag, either call the method directly
81
+ api.reset_anomalous_users([12345, 23456])
82
+ # Or use the :force_anomalous_override option when calling track_events or track_multi
83
+ api.track_events(event, force_anomalous_override: true)
78
84
  ```
79
85
 
80
86
  Data export:
@@ -4,11 +4,11 @@ module LeanplumApi
4
4
  EXPORT_RUNNING = 'RUNNING'
5
5
  EXPORT_FINISHED = 'FINISHED'
6
6
 
7
+ class LeanplumValidationException < RuntimeError; end
8
+
7
9
  def initialize(options = {})
8
10
  fail 'LeanplumApi not configured yet!' unless LeanplumApi.configuration
9
-
10
- @logger = options[:logger] || LeanplumApiLogger.new(File.join(LeanplumApi.configuration.log_path, "#{$$}_leanplum_#{Time.now.utc.strftime('%Y-%m-%d_%H:%M:%S')}.log"))
11
- @http = LeanplumApi::HTTP.new(logger: @logger)
11
+ @http = LeanplumApi::HTTP.new
12
12
  end
13
13
 
14
14
  def set_user_attributes(user_attributes, options = {})
@@ -24,12 +24,11 @@ module LeanplumApi
24
24
  # Set the :force_anomalous_override to catch warnings from leanplum about anomalous events and force them to not
25
25
  # be considered anomalous
26
26
  def track_multi(events = nil, user_attributes = nil, options = {})
27
- events = arrayify(events)
28
- user_attributes = arrayify(user_attributes)
27
+ events = Array.wrap(events)
28
+ user_attributes = Array.wrap(user_attributes)
29
29
 
30
30
  request_data = user_attributes.map { |h| build_user_attributes_hash(h) } + events.map { |h| build_event_attributes_hash(h) }
31
31
  response = @http.post(request_data)
32
- validate_response(events + user_attributes, response)
33
32
 
34
33
  if options[:force_anomalous_override]
35
34
  user_ids_to_reset = []
@@ -48,7 +47,7 @@ module LeanplumApi
48
47
  # They recommend using the automatic export to S3 if possible.
49
48
  def export_data(start_time, end_time = nil)
50
49
  fail "Start time #{start_time} after end time #{end_time}" if end_time && start_time > end_time
51
- @logger.info("Requesting data export from #{start_time} to #{end_time}...")
50
+ LeanplumApi.configuration.logger.info("Requesting data export from #{start_time} to #{end_time}...")
52
51
 
53
52
  # Because of open questions about how startTime and endTime work (or don't work, as the case may be), we
54
53
  # only want to pass the dates unless start and end times are specifically requested.
@@ -72,17 +71,12 @@ module LeanplumApi
72
71
  params.merge!(s3ObjectPrefix: LeanplumApi.configuration.s3_object_prefix) if LeanplumApi.configuration.s3_object_prefix
73
72
  end
74
73
 
75
- response = data_export_connection.get(params).body['response'].first
76
- if response['success'] == true
77
- response['jobId']
78
- else
79
- fail "No success message! Response: #{response}"
80
- end
74
+ data_export_connection.get(params).body['response'].first['jobId']
81
75
  end
82
76
 
83
77
  # See leanplum docs.
84
78
  # The segment syntax is identical to that produced by the "Insert Value" feature on the dashboard.
85
- # Examples: 'Country = "US"', '{Country = US} and {App version = 1}'.
79
+ # Examples: 'Country = "US"', '{Country = "US"} and {App version = 1}'.
86
80
  def export_users(segment, ab_test_id)
87
81
  data_export_connection.get(action: 'exportUsers', segment: segment, ab_test_id: ab_test_id)
88
82
  end
@@ -90,8 +84,8 @@ module LeanplumApi
90
84
  def get_export_results(job_id)
91
85
  response = data_export_connection.get(action: 'getExportResults', jobId: job_id).body['response'].first
92
86
  if response['state'] == EXPORT_FINISHED
93
- @logger.info("Export finished.")
94
- @logger.debug(" Response: #{response}")
87
+ LeanplumApi.configuration.logger.info("Export finished.")
88
+ LeanplumApi.configuration.logger.debug(" Response: #{response}")
95
89
  {
96
90
  files: response['files'],
97
91
  number_of_sessions: response['numSessions'],
@@ -106,7 +100,7 @@ module LeanplumApi
106
100
 
107
101
  def wait_for_job(job_id, polling_interval = 60)
108
102
  while get_export_results(job_id)[:state] != EXPORT_FINISHED
109
- @logger.debug("Polling job #{job_id}: #{get_export_results(job_id)}")
103
+ LeanplumApi.configuration.logger.debug("Polling job #{job_id}: #{get_export_results(job_id)}")
110
104
  sleep(polling_interval)
111
105
  end
112
106
  get_export_results(job_id)
@@ -145,26 +139,25 @@ module LeanplumApi
145
139
  # Calling this method after you pass old events will fix that for all events for the specified user_id
146
140
  # For some reason this API feature requires the developer key
147
141
  def reset_anomalous_users(user_ids)
148
- user_ids = arrayify(user_ids)
142
+ user_ids = Array.wrap(user_ids)
149
143
  request_data = user_ids.map { |user_id| { 'action' => 'setUserAttributes', 'resetAnomalies' => true, 'userId' => user_id } }
150
- response = development_connection.post(request_data)
151
- validate_response(request_data, response)
144
+ development_connection.post(request_data)
152
145
  end
153
146
 
154
147
  private
155
148
 
156
149
  # Only instantiated for data export endpoint calls
157
150
  def data_export_connection
158
- @data_export ||= LeanplumApi::DataExport.new(logger: @logger)
151
+ @data_export ||= LeanplumApi::DataExport.new
159
152
  end
160
153
 
161
154
  # Only instantiated for ContentReadOnly calls (AB tests)
162
155
  def content_read_only_connection
163
- @content_read_only ||= LeanplumApi::ContentReadOnly.new(logger: @logger)
156
+ @content_read_only ||= LeanplumApi::ContentReadOnly.new
164
157
  end
165
158
 
166
159
  def development_connection
167
- @development ||= LeanplumApi::Development.new(logger: @logger)
160
+ @development ||= LeanplumApi::Development.new
168
161
  end
169
162
 
170
163
  def extract_user_id_or_device_id_hash(hash)
@@ -217,35 +210,5 @@ module LeanplumApi
217
210
  end
218
211
  new_hash
219
212
  end
220
-
221
- # In case leanplum decides your events are too old, they will send a warning.
222
- # Right now we aren't responding to this directly.
223
- # '{"response":[{"success":true,"warning":{"message":"Anomaly detected: time skew. User will be excluded from analytics."}}]}'
224
- def validate_response(input, response)
225
- success_indicators = response.body['response']
226
- if success_indicators.size != input.size
227
- fail "Attempted to update #{input.size} records but only received confirmation for #{success_indicators.size}!"
228
- end
229
-
230
- failure_indices = []
231
- success_indicators.each_with_index do |s,i|
232
- if s['success'].to_s != 'true'
233
- @logger.error("Unsuccessful attempt to update at position #{i}: #{input[i]}")
234
- failure_indices << i
235
- else
236
- @logger.debug("Successfully updated position #{i}: #{input[i]}")
237
- end
238
- end
239
-
240
- fail LeanplumValidationException.new('Failed to update') if failure_indices.size > 0
241
- end
242
-
243
- def arrayify(x)
244
- if x && !x.is_a?(Array)
245
- [x]
246
- else
247
- x || []
248
- end
249
- end
250
213
  end
251
214
  end
@@ -26,6 +26,7 @@ module LeanplumApi
26
26
  attr_accessor :api_version
27
27
  attr_accessor :developer_mode
28
28
  attr_accessor :log_path
29
+ attr_accessor :logger
29
30
  attr_accessor :timeout_seconds
30
31
 
31
32
  # Optional configuration for exporting raw data to S3.
@@ -36,10 +37,13 @@ module LeanplumApi
36
37
  attr_accessor :s3_object_prefix
37
38
 
38
39
  def initialize
39
- @log_path = 'log'
40
40
  @api_version = DEFAULT_LEANPLUM_API_VERSION
41
41
  @developer_mode = false
42
42
  @timeout_seconds = 600
43
+ @logger = LeanplumApi::Logger.new(STDOUT)
44
+
45
+ # Deprecated
46
+ @log_path = 'log'
43
47
  end
44
48
  end
45
49
  end
@@ -0,0 +1,45 @@
1
+ module LeanplumApi
2
+ class BadResponseError < RuntimeError; end
3
+ class ResourceNotFoundError < RuntimeError; end
4
+
5
+ class ResponseValidation < Faraday::Middleware
6
+ Faraday::Request.register_middleware(leanplum_response_validation: self)
7
+
8
+ def call(environment)
9
+ operations = nil
10
+
11
+ if environment.body
12
+ operations = environment.body[:data] if environment.body[:data] && environment.body[:data].is_a?(Array)
13
+ environment.body = environment.body.to_json
14
+ end
15
+
16
+ @app.call(environment).on_complete do |response|
17
+ fail ResourceNotFoundError, response.inspect if response.status == 404
18
+ fail BadResponseError, response.inspect unless response.status == 200 && response.body['response']
19
+ fail BadResponseError, "No :success key in #{response.inspect}!" unless response.body['response'].is_a?(Array) && response.body['response'].first.has_key?('success')
20
+ fail BadResponseError, "Not a success! Response: #{response.inspect}" unless response.body['response'].first['success'] == true
21
+ validate_operation_success(operations, response) if operations
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def validate_operation_success(operations, response)
28
+ success_indicators = response.body['response']
29
+ if success_indicators.size != operations.size
30
+ fail "Attempted to update #{operations.size} records but only received confirmation for #{success_indicators.size}!"
31
+ end
32
+
33
+ failures = []
34
+ success_indicators.each_with_index do |s, i|
35
+ if s['success'].to_s != 'true'
36
+ LeanplumApi.configuration.logger.error("Unsuccessful attempt to update at position #{i}: #{operations[i]}")
37
+ failures << { operation: operations[i], error: s }
38
+ end
39
+ LeanplumApi.configuration.logger.warn("Warning for operation #{operations[i]}: #{s['warning']}") if s['warning']
40
+ end
41
+
42
+ fail LeanplumValidationException.new("Operation failures: #{failures}") if failures.size > 0
43
+ end
44
+ end
45
+ end
@@ -12,7 +12,7 @@ module LeanplumApi
12
12
 
13
13
  def post(payload)
14
14
  connection.post("#{LEANPLUM_API_PATH}?#{authed_multi_param_string}") do |request|
15
- request.body = { data: payload }.to_json
15
+ request.body = { data: payload }
16
16
  end
17
17
  end
18
18
 
@@ -44,7 +44,7 @@ module LeanplumApi
44
44
  }
45
45
 
46
46
  @connection ||= Faraday.new(options) do |connection|
47
- connection.request :json
47
+ connection.request :leanplum_response_validation
48
48
 
49
49
  connection.response :logger, @logger, bodies: true if api_debug?
50
50
  connection.response :json, :content_type => /\bjson$/
@@ -1,7 +1,7 @@
1
1
  require 'logger'
2
2
 
3
3
  module LeanplumApi
4
- class LeanplumApiLogger < Logger
4
+ class Logger < ::Logger
5
5
  def format_message(severity, timestamp, progname, msg)
6
6
  @keys ||= [
7
7
  LeanplumApi.configuration.production_key,
@@ -1,3 +1,3 @@
1
1
  module LeanplumApi
2
- VERSION = '1.3.1'
2
+ VERSION = '1.3.5'
3
3
  end
data/lib/leanplum_api.rb CHANGED
@@ -1,15 +1,9 @@
1
1
  require 'faraday'
2
2
  require 'active_support/all'
3
3
 
4
- require 'leanplum_api/api'
5
- require 'leanplum_api/configuration'
6
- require 'leanplum_api/content_read_only'
7
- require 'leanplum_api/data_export'
8
- require 'leanplum_api/development'
9
- require 'leanplum_api/exception'
10
- require 'leanplum_api/http'
11
- require 'leanplum_api/logger'
12
- require 'leanplum_api/version'
4
+ path = File.join(File.expand_path(File.dirname(__FILE__)), 'leanplum_api')
5
+ Dir["#{path}/*.rb"].each { |f| require f }
6
+ Dir["#{path}/**/*.rb"].each { |f| require f }
13
7
 
14
8
  module LeanplumApi
15
9
  end
data/spec/api_spec.rb CHANGED
@@ -152,10 +152,6 @@ describe LeanplumApi::API do
152
152
  end
153
153
 
154
154
  context 'data export methods' do
155
- let(:s3_bucket_name) { 'bucket' }
156
- let(:s3_access_key) { 's3_access_key' }
157
- let(:s3_access_id) { 's3_access_id' }
158
-
159
155
  around(:all) do |example|
160
156
  LeanplumApi.configure do |c|
161
157
  c.developer_mode = false
@@ -165,17 +161,27 @@ describe LeanplumApi::API do
165
161
  end
166
162
 
167
163
  context 'export_data' do
168
- it 'should request a data export job with a starttime' do
169
- VCR.use_cassette('export_data') do
170
- expect { api.export_data(Time.at(1438660800).utc) }.to raise_error(/No matching data found/)
164
+ context 'regular export' do
165
+ it 'should request a data export job with a starttime' do
166
+ VCR.use_cassette('export_data') do
167
+ expect { api.export_data(Time.at(1438660800).utc) }.to raise_error LeanplumApi::ResourceNotFoundError
168
+ end
171
169
  end
172
- end
173
170
 
174
- it 'should request a data export job with start and end dates' do
175
- VCR.use_cassette('export_data_dates') do
176
- expect { api.export_data(Date.new(2015, 9, 5), Date.new(2015, 9, 6)) }.to raise_error(/No matching data found/)
171
+ it 'should request a data export job with start and end dates' do
172
+ VCR.use_cassette('export_data_dates') do
173
+ expect { api.export_data(Date.new(2015, 9, 5), Date.new(2015, 9, 6)) }.to raise_error LeanplumApi::ResourceNotFoundError
174
+ end
177
175
  end
178
176
  end
177
+
178
+ context 's3 export' do
179
+ let(:s3_bucket_name) { 'bucket' }
180
+ let(:s3_access_key) { 's3_access_key' }
181
+ let(:s3_access_id) { 's3_access_id' }
182
+
183
+ it 'should request an S3 export'
184
+ end
179
185
  end
180
186
 
181
187
  context 'get_export_results' do
@@ -195,34 +201,44 @@ describe LeanplumApi::API do
195
201
  end
196
202
 
197
203
  context 'content read only methods' do
198
- it 'gets ab tests' do
199
- VCR.use_cassette('get_ab_tests') do
200
- expect(api.get_ab_tests).to eq([])
204
+ context 'ab tests' do
205
+ it 'gets ab tests' do
206
+ VCR.use_cassette('get_ab_tests') do
207
+ expect(api.get_ab_tests).to eq([])
208
+ end
201
209
  end
202
- end
203
210
 
204
- it 'gets an ab test' do
205
- VCR.use_cassette('get_ab_test') do
206
- expect(api.get_ab_tests(1)).to eq([])
211
+ it 'gets an ab test' do
212
+ VCR.use_cassette('get_ab_test') do
213
+ expect(api.get_ab_tests(1)).to eq([])
214
+ end
207
215
  end
208
216
  end
209
217
 
210
- it 'gets messages' do
211
- VCR.use_cassette('get_messages') do
212
- expect(api.get_messages).to eq([{
213
- "id" => 5670583287676928,
214
- "created" => 1440091595.799,
215
- "name" => "New Message",
216
- "active" => false,
217
- "messageType" => "Push Notification"
218
- }])
218
+ context 'messages' do
219
+ it 'gets messages' do
220
+ VCR.use_cassette('get_messages') do
221
+ expect(api.get_messages).to eq([{
222
+ "id" => 5670583287676928,
223
+ "created" => 1440091595.799,
224
+ "name" => "New Message",
225
+ "active" => false,
226
+ "messageType" => "Push Notification"
227
+ }])
228
+ end
229
+ end
230
+
231
+ it 'throws exception on missing message' do
232
+ VCR.use_cassette('missing_message') do
233
+ expect { api.get_message(1234) }.to raise_error LeanplumApi::ResourceNotFoundError
234
+ end
219
235
  end
220
236
  end
221
237
 
222
238
  it 'gets vars' do
223
239
  VCR.use_cassette('get_vars') do
224
240
  vars = api.get_vars(first_user_id)
225
- expect(vars).to eq({'test_var' => 1})
241
+ expect(vars).to eq({ 'test_var' => 1 })
226
242
  end
227
243
  end
228
244
  end
@@ -0,0 +1,40 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://www.leanplum.com/api?action=getMessage&apiVersion=1.0.6&appId=<LEANPLUM_APP_ID>&clientKey=<LEANPLUM_CONTENT_READ_ONLY_KEY>&devMode=false&id=1234
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.9.2
12
+ Accept-Encoding:
13
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
14
+ Accept:
15
+ - "*/*"
16
+ response:
17
+ status:
18
+ code: 404
19
+ message: Not Found
20
+ headers:
21
+ Access-Control-Allow-Origin:
22
+ - "*"
23
+ Content-Type:
24
+ - application/json
25
+ Date:
26
+ - Mon, 04 Jan 2016 18:15:51 GMT
27
+ Server:
28
+ - Google Frontend
29
+ Cache-Control:
30
+ - private
31
+ Alt-Svc:
32
+ - quic=":443"; ma=604800; v="30,29,28,27,26,25"
33
+ Transfer-Encoding:
34
+ - chunked
35
+ body:
36
+ encoding: UTF-8
37
+ string: '{"response":[{"error":{"message":"Message not found."},"success":false}]}'
38
+ http_version:
39
+ recorded_at: Wed, 12 Aug 2015 00:00:00 GMT
40
+ recorded_with: VCR 2.9.3
data/spec/spec_helper.rb CHANGED
@@ -19,6 +19,7 @@ RSpec.configure do |config|
19
19
  configuration.data_export_key = ENV.fetch('LEANPLUM_DATA_EXPORT_KEY')
20
20
  configuration.content_read_only_key = ENV.fetch('LEANPLUM_CONTENT_READ_ONLY_KEY')
21
21
  configuration.development_key = ENV.fetch('LEANPLUM_DEVELOPMENT_KEY')
22
+ configuration.logger.level = Logger::FATAL
22
23
  end
23
24
 
24
25
  Timecop.freeze('2015-08-12'.to_time.utc)
@@ -37,7 +38,7 @@ VCR.configure do |c|
37
38
  c.filter_sensitive_data('<LEANPLUM_APP_ID>') { ENV.fetch('LEANPLUM_APP_ID') }
38
39
  c.filter_sensitive_data('<LEANPLUM_CONTENT_READ_ONLY_KEY>') { ENV.fetch('LEANPLUM_CONTENT_READ_ONLY_KEY') }
39
40
  c.filter_sensitive_data('<LEANPLUM_DATA_EXPORT_KEY>') { ENV.fetch('LEANPLUM_DATA_EXPORT_KEY') }
40
- c.filter_sensitive_data('<LEANPLUM_DEVELOPMENT_KEY>') { ENV.fetch('LEANPLUM_DEVELOPMENT_KEY') }
41
+ c.filter_sensitive_data('<LEANPLUM_DEVELOPMENT_KEY>') { ENV.fetch('LEANPLUM_DEVELOPMENT_KEY') }
41
42
 
42
43
  c.default_cassette_options = {
43
44
  match_requests_on: [:method, :uri, :body]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leanplum_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lumos Labs, Inc.
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: awesome_print
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: faraday
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -145,7 +159,7 @@ files:
145
159
  - lib/leanplum_api/content_read_only.rb
146
160
  - lib/leanplum_api/data_export.rb
147
161
  - lib/leanplum_api/development.rb
148
- - lib/leanplum_api/exception.rb
162
+ - lib/leanplum_api/faraday_middleware/response_validation.rb
149
163
  - lib/leanplum_api/http.rb
150
164
  - lib/leanplum_api/logger.rb
151
165
  - lib/leanplum_api/version.rb
@@ -159,6 +173,7 @@ files:
159
173
  - spec/fixtures/vcr/get_export_results.yml
160
174
  - spec/fixtures/vcr/get_messages.yml
161
175
  - spec/fixtures/vcr/get_vars.yml
176
+ - spec/fixtures/vcr/missing_message.yml
162
177
  - spec/fixtures/vcr/reset_anomalous_user.yml
163
178
  - spec/fixtures/vcr/set_user_attributes.yml
164
179
  - spec/fixtures/vcr/track_events.yml
@@ -201,6 +216,7 @@ test_files:
201
216
  - spec/fixtures/vcr/get_export_results.yml
202
217
  - spec/fixtures/vcr/get_messages.yml
203
218
  - spec/fixtures/vcr/get_vars.yml
219
+ - spec/fixtures/vcr/missing_message.yml
204
220
  - spec/fixtures/vcr/reset_anomalous_user.yml
205
221
  - spec/fixtures/vcr/set_user_attributes.yml
206
222
  - spec/fixtures/vcr/track_events.yml
@@ -1,4 +0,0 @@
1
- module LeanplumApi
2
- class LeanplumValidationException < Exception
3
- end
4
- end