embulk-input-marketo 0.5.6 → 0.5.7.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.github/PULL_REQUEST_TEMPLATE.md +37 -0
  3. data/.gitignore +11 -2
  4. data/.travis.yml +5 -45
  5. data/LICENSE.txt +21 -0
  6. data/README.md +14 -65
  7. data/build.gradle +102 -0
  8. data/config/checkstyle/checkstyle.xml +128 -0
  9. data/config/checkstyle/default.xml +108 -0
  10. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  11. data/gradle/wrapper/gradle-wrapper.properties +6 -0
  12. data/gradlew +169 -0
  13. data/gradlew.bat +84 -0
  14. data/lib/embulk/input/marketo.rb +3 -0
  15. data/settings.gradle +1 -0
  16. data/src/main/java/org/embulk/input/marketo/CsvTokenizer.java +677 -0
  17. data/src/main/java/org/embulk/input/marketo/MarketoInputPlugin.java +15 -0
  18. data/src/main/java/org/embulk/input/marketo/MarketoInputPluginDelegate.java +77 -0
  19. data/src/main/java/org/embulk/input/marketo/MarketoService.java +30 -0
  20. data/src/main/java/org/embulk/input/marketo/MarketoServiceImpl.java +176 -0
  21. data/src/main/java/org/embulk/input/marketo/MarketoUtils.java +172 -0
  22. data/src/main/java/org/embulk/input/marketo/delegate/ActivityBulkExtractInputPlugin.java +63 -0
  23. data/src/main/java/org/embulk/input/marketo/delegate/CampaignInputPlugin.java +67 -0
  24. data/src/main/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPlugin.java +61 -0
  25. data/src/main/java/org/embulk/input/marketo/delegate/LeadWithListInputPlugin.java +58 -0
  26. data/src/main/java/org/embulk/input/marketo/delegate/LeadWithProgramInputPlugin.java +56 -0
  27. data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPlugin.java +260 -0
  28. data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseInputPluginDelegate.java +69 -0
  29. data/src/main/java/org/embulk/input/marketo/exception/MarketoAPIException.java +30 -0
  30. data/src/main/java/org/embulk/input/marketo/model/MarketoAccessTokenResponse.java +92 -0
  31. data/src/main/java/org/embulk/input/marketo/model/MarketoBulkExtractRequest.java +59 -0
  32. data/src/main/java/org/embulk/input/marketo/model/MarketoError.java +40 -0
  33. data/src/main/java/org/embulk/input/marketo/model/MarketoField.java +91 -0
  34. data/src/main/java/org/embulk/input/marketo/model/MarketoResponse.java +81 -0
  35. data/src/main/java/org/embulk/input/marketo/model/filter/DateRangeFilter.java +31 -0
  36. data/src/main/java/org/embulk/input/marketo/model/filter/ListFilter.java +10 -0
  37. data/src/main/java/org/embulk/input/marketo/model/filter/MarketoFilter.java +8 -0
  38. data/src/main/java/org/embulk/input/marketo/rest/MarketoBaseRestClient.java +226 -0
  39. data/src/main/java/org/embulk/input/marketo/rest/MarketoFileResponseEntityReader.java +69 -0
  40. data/src/main/java/org/embulk/input/marketo/rest/MarketoRESTEndpoint.java +44 -0
  41. data/src/main/java/org/embulk/input/marketo/rest/MarketoResponseJetty92EntityReader.java +88 -0
  42. data/src/main/java/org/embulk/input/marketo/rest/MarketoRestClient.java +332 -0
  43. data/src/main/java/org/embulk/input/marketo/rest/RecordPagingIterable.java +130 -0
  44. data/src/test/java/org/embulk/input/marketo/TestMarketoInputPlugin.java +5 -0
  45. data/src/test/java/org/embulk/input/marketo/rest/MarketoBaseRestClientTest.java +220 -0
  46. metadata +65 -222
  47. data/.ruby-version +0 -1
  48. data/.travis.yml.erb +0 -42
  49. data/Gemfile +0 -3
  50. data/LICENSE +0 -13
  51. data/Rakefile +0 -20
  52. data/embulk-input-marketo.gemspec +0 -28
  53. data/gemfiles/embulk-latest +0 -4
  54. data/gemfiles/template.erb +0 -4
  55. data/lib/embulk/input/marketo/activity_log.rb +0 -103
  56. data/lib/embulk/input/marketo/base.rb +0 -139
  57. data/lib/embulk/input/marketo/lead.rb +0 -143
  58. data/lib/embulk/input/marketo_api.rb +0 -22
  59. data/lib/embulk/input/marketo_api/soap/activity_log.rb +0 -103
  60. data/lib/embulk/input/marketo_api/soap/base.rb +0 -135
  61. data/lib/embulk/input/marketo_api/soap/lead.rb +0 -91
  62. data/test/activity_log_fixtures.rb +0 -216
  63. data/test/embulk/input/marketo/test_activity_log.rb +0 -444
  64. data/test/embulk/input/marketo/test_base.rb +0 -76
  65. data/test/embulk/input/marketo/test_lead.rb +0 -605
  66. data/test/embulk/input/marketo_api/soap/test_activity_log.rb +0 -154
  67. data/test/embulk/input/marketo_api/soap/test_base.rb +0 -96
  68. data/test/embulk/input/marketo_api/soap/test_lead.rb +0 -139
  69. data/test/embulk/input/test_marketo_api.rb +0 -28
  70. data/test/lead_fixtures.rb +0 -111
  71. data/test/mute_logger.rb +0 -7
  72. data/test/override_assert_raise.rb +0 -18
  73. data/test/prepare_embulk.rb +0 -15
  74. data/test/run-test.rb +0 -26
  75. data/test/savon_helper.rb +0 -17
@@ -1,605 +0,0 @@
1
- require "prepare_embulk"
2
- require "lead_fixtures"
3
- require "mute_logger"
4
- require "override_assert_raise"
5
- require "embulk/input/marketo/lead"
6
-
7
- module Embulk
8
- module Input
9
- module Marketo
10
- class LeadTest < Test::Unit::TestCase
11
- include LeadFixtures
12
- include MuteLogger
13
- include OverrideAssertRaise
14
-
15
- def test_target
16
- assert_equal(:lead, Lead.target)
17
- end
18
-
19
- def setup_soap
20
- @soap = MarketoApi::Soap::Lead.new(settings[:endpoint], settings[:wsdl], settings[:user_id], settings[:encryption_key])
21
-
22
- stub(Lead).soap_client(task) { @soap }
23
- end
24
-
25
- def setup_plugin
26
- @page_builder = Object.new
27
- any_instance_of(Embulk::Input::Marketo::Lead) do |klass|
28
- stub(klass).index { 0 }
29
- end
30
- @plugin = Lead.new(task, nil, nil, @page_builder)
31
- end
32
-
33
- def test_invalid_from_datetime_to_datetime
34
- control = proc {} # dummy
35
-
36
- settings = {
37
- endpoint: "https://marketo.example.com",
38
- wsdl: "https://marketo.example.com/?wsdl",
39
- user_id: "user_id",
40
- encryption_key: "TOPSECRET",
41
- columns: [
42
- {"name" => "Name", "type" => "string"},
43
- ],
44
- from_datetime: Time.now + 3600,
45
- to_datetime: Time.now,
46
- }
47
- config = DataSource[settings.to_a]
48
-
49
- assert_raise(ConfigError) do
50
- Lead.transaction(config, &control)
51
- end
52
- end
53
-
54
- data do
55
- [
56
- ["endpoint", "endpoint"],
57
- ["wsdl", "wsdl"],
58
- ]
59
- end
60
- def test_invalid_url(key)
61
- control = proc {} # dummy
62
-
63
- settings = {
64
- endpoint: "https://marketo.example.com",
65
- wsdl: "https://marketo.example.com/?wsdl",
66
- user_id: "user_id",
67
- encryption_key: "TOPSECRET",
68
- columns: [
69
- {"name" => "Name", "type" => "string"},
70
- ],
71
- from_datetime: Time.now,
72
- to_datetime: Time.now + 3600,
73
- }
74
- settings[key.to_sym] = " invalid url "
75
- config = DataSource[settings.to_a]
76
-
77
- assert_raise(ConfigError) do
78
- Lead.transaction(config, &control)
79
- end
80
- end
81
-
82
- def test_invalid_datetime_given
83
- control = proc {} # dummy
84
-
85
- settings = {
86
- endpoint: "https://marketo.example.com",
87
- wsdl: "https://marketo.example.com/?wsdl",
88
- user_id: "user_id",
89
- encryption_key: "TOPSECRET",
90
- from_datetime: "invalid time from",
91
- to_datetime: "invalid time to",
92
- columns: [
93
- {"name" => "Name", "type" => "string"},
94
- ]
95
- }
96
- config = DataSource[settings.to_a]
97
-
98
- assert_raise(ConfigError) do
99
- Lead.transaction(config, &control)
100
- end
101
- end
102
-
103
- def test_wrong_type
104
- control = proc {} # dummy
105
-
106
- settings = {
107
- endpoint: "https://marketo.example.com",
108
- wsdl: "https://marketo.example.com/?wsdl",
109
- user_id: "user_id",
110
- encryption_key: "TOPSECRET",
111
- from_datetime: "invalid time from",
112
- to_datetime: "invalid time to",
113
- columns: [
114
- {"name" => "Name", "type" => "timestamp"},
115
- ]
116
- }
117
-
118
- config = DataSource[settings.to_a]
119
-
120
- assert_raise(ConfigError) do
121
- Lead.transaction(config, &control)
122
- end
123
- end
124
-
125
- def test_same_datetimes_given
126
- control = proc { [] } # dummy (#resume method returns [])
127
- datetime = Time.now.to_s
128
-
129
- settings = {
130
- endpoint: "https://marketo.example.com",
131
- wsdl: "https://marketo.example.com/?wsdl",
132
- user_id: "user_id",
133
- encryption_key: "TOPSECRET",
134
- from_datetime: datetime,
135
- to_datetime: datetime,
136
- columns: [
137
- {"name" => "Name", "type" => "string"},
138
- ]
139
- }
140
- config = DataSource[settings.to_a]
141
-
142
- assert_equal({}, Lead.transaction(config, &control))
143
- end
144
-
145
- class RunTest < self
146
- def setup
147
- setup_soap
148
- setup_plugin
149
- end
150
-
151
- def test_run_through
152
- mute_logger
153
- stub(@plugin).preview? { false }
154
-
155
- any_instance_of(Savon::Client) do |klass|
156
- mock(klass).call(:get_multiple_leads, message: request) do
157
- savon_response(xml_lead_response)
158
- end
159
-
160
- mock(klass).call(:get_multiple_leads, message: request.merge(stream_position: stream_position)) do
161
- savon_response(xml_lead_next)
162
- end
163
- end
164
-
165
- from = Time.parse(from_datetime)
166
- mock(@page_builder).add(["manyo", from])
167
- mock(@page_builder).add(["everyleaf", from])
168
- mock(@page_builder).add(["ten-thousand-leaf", from])
169
- mock(@page_builder).finish
170
-
171
- @plugin.init
172
- @plugin.run
173
- end
174
-
175
- def test_run_no_processed_time_columns
176
- mute_logger
177
-
178
- no_processed__task = task.merge(append_processed_time_column: false)
179
- @plugin = Lead.new(no_processed__task, nil, nil, @page_builder)
180
- stub(@plugin).preview? { false }
181
-
182
- any_instance_of(Savon::Client) do |klass|
183
- mock(klass).call(:get_multiple_leads, message: request) do
184
- savon_response(xml_lead_response)
185
- end
186
-
187
- mock(klass).call(:get_multiple_leads, message: request.merge(stream_position: stream_position)) do
188
- savon_response(xml_lead_next)
189
- end
190
- end
191
-
192
- mock(@page_builder).add(["manyo"])
193
- mock(@page_builder).add(["everyleaf"])
194
- mock(@page_builder).add(["ten-thousand-leaf"])
195
- mock(@page_builder).finish
196
-
197
- @plugin.init
198
- @plugin.run
199
- end
200
-
201
- def test_run_task_report
202
- mute_logger
203
- # do not requests
204
- stub(@page_builder).finish
205
- stub(@plugin.soap).each { }
206
-
207
- task_report = @plugin.run
208
- assert_equal({}, task_report)
209
- end
210
-
211
- def test_preview_through
212
- mute_logger
213
- stub(@plugin).preview? { true }
214
-
215
- any_instance_of(Savon::Client) do |klass|
216
- mock(klass).call(:get_multiple_leads, message: request.merge(batch_size: Lead::PREVIEW_COUNT)) do
217
- savon_response(xml_lead_preview)
218
- end
219
- end
220
-
221
- from = Time.parse(from_datetime)
222
- Lead::PREVIEW_COUNT.times do |count|
223
- mock(@page_builder).add(["manyo#{count}", from])
224
- end
225
- mock(@page_builder).finish
226
-
227
- @plugin.init
228
- @plugin.run
229
- end
230
-
231
- def test_preview_will_stop_fetching_when_defined_times_added
232
- mute_logger
233
- stub(@plugin).preview? { true }
234
- @plugin.instance_variable_set(:@ranges, @plugin.task[:ranges].first * 3) # multiple ranges
235
-
236
- any_instance_of(Savon::Client) do |klass|
237
- mock(klass).call(:get_multiple_leads, anything) do
238
- savon_response(xml_lead_preview)
239
- end
240
- end
241
-
242
- mock(@page_builder).add(anything).times(Lead::PREVIEW_COUNT)
243
- mock(@page_builder).finish
244
-
245
- @plugin.init
246
- @plugin.run
247
- end
248
-
249
- def test_retry
250
- setup_plugin
251
-
252
- any_instance_of(Savon::Client) do |klass|
253
- stub(klass).call(:get_multiple_leads, anything) do
254
- raise "foo"
255
- end
256
- end
257
-
258
- mock(Embulk.logger).warn(/Retrying/).times(task[:retry_limit])
259
- stub(Embulk.logger).info {}
260
-
261
- assert_raise do
262
- @plugin.init
263
- @plugin.run
264
- end
265
- end
266
-
267
- class SavonCallTest < self
268
- def test_soap_error
269
- nori_options = {
270
- :strip_namespaces => true,
271
- :convert_tags_to => lambda { |tag| tag.snakecase.to_sym},
272
- :convert_attributes_to => lambda { |k,v| [k,v] },
273
- }
274
- assert_raise(Embulk::ConfigError) do
275
- @soap.send(:catch_unretryable_error) do
276
- raise Savon::SOAPFault.new(nil, Nori.new(nori_options), xml)
277
- end
278
- end
279
- end
280
-
281
- def test_http_error_on_client
282
- assert_raise(Embulk::ConfigError) do
283
- @soap.send(:catch_unretryable_error) do
284
- raise Savon::HTTPError.new(HTTPI::Response.new(500, {}, xml("20000")))
285
- end
286
- end
287
- end
288
-
289
- def test_http_error_on_server
290
- assert_raise(Savon::HTTPError) do
291
- @soap.send(:catch_unretryable_error) do
292
- # Internal Error
293
- raise Savon::HTTPError.new(HTTPI::Response.new(500, {}, xml("10001")))
294
- end
295
- end
296
- end
297
-
298
- def test_socket_error
299
- mute_logger
300
- stub(@soap).endpoint { "http://foo.test/" }
301
-
302
- assert_raise(Embulk::ConfigError) do
303
- @plugin.init
304
- @plugin.run
305
- end
306
- end
307
-
308
- def xml(code = nil, message = nil)
309
- <<-XML
310
- <?xml version="1.0" encoding="UTF-8"?>
311
- <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault>
312
- <faultcode>SOAP-ENV:Client</faultcode>
313
- <faultstring>#{message || "20014 - Authentication failed"}</faultstring>
314
- <detail>
315
- <ns1:serviceException xmlns:ns1="http://www.marketo.com/mktows/">
316
- <name>mktServiceException</name>
317
- <message>#{message || "Authentication failed (20014)"}</message>
318
- <code>#{code || "20014"}</code>
319
- </ns1:serviceException></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
320
- XML
321
- end
322
-
323
- end
324
-
325
- class TestTimeslice < self
326
- class TestGenerateTimeRange < self
327
- def setup
328
- super
329
- mute_logger
330
- end
331
-
332
- data do
333
- {
334
- "8/1 to 8/2" => ["2015-08-01 00:00:00", "2015-08-02 00:00:00", 24],
335
- "over the days" => ["2015-08-01 19:00:00", "2015-08-03 05:00:00", 34],
336
- "odd times" => ["2015-08-01 11:11:11", "2015-08-01 22:22:22", 12],
337
- }
338
- end
339
- def test_generate_time_range_by_1hour(data)
340
- from, to, count = data
341
- range = Lead.generate_time_range(from, to)
342
- assert_equal count, range.length
343
- end
344
-
345
- def test_if_to_is_nil_use_time_now
346
- from = "2000-01-01"
347
- now = Time.now
348
- stub(Time).now { now }
349
-
350
- range = Lead.generate_time_range(from, nil)
351
- assert_equal now, range.last["to"]
352
- end
353
- end
354
-
355
- def test_timeslice
356
- from = "2015-08-02 20:00:00"
357
- to = "2015-08-03 08:08:08"
358
- count = 4
359
-
360
- raw_expect = [
361
- [
362
- {from: "2015-08-02 20:00:00", to: "2015-08-02 21:00:00"},
363
- {from: "2015-08-02 21:00:00", to: "2015-08-02 22:00:00"},
364
- {from: "2015-08-02 22:00:00", to: "2015-08-02 23:00:00"},
365
- {from: "2015-08-02 23:00:00", to: "2015-08-03 00:00:00"},
366
- ],
367
- [
368
- {from: "2015-08-03 00:00:00", to: "2015-08-03 01:00:00"},
369
- {from: "2015-08-03 01:00:00", to: "2015-08-03 02:00:00"},
370
- {from: "2015-08-03 02:00:00", to: "2015-08-03 03:00:00"},
371
- {from: "2015-08-03 03:00:00", to: "2015-08-03 04:00:00"},
372
- ],
373
- [
374
- {from: "2015-08-03 04:00:00", to: "2015-08-03 05:00:00"},
375
- {from: "2015-08-03 05:00:00", to: "2015-08-03 06:00:00"},
376
- {from: "2015-08-03 06:00:00", to: "2015-08-03 07:00:00"},
377
- {from: "2015-08-03 07:00:00", to: "2015-08-03 08:00:00"},
378
- ],
379
- [
380
- {from: "2015-08-03 08:00:00", to: "2015-08-03 08:08:08"},
381
- ]
382
- ]
383
-
384
- expect = raw_expect.map do |slice|
385
- slice.map do |range|
386
- {
387
- "from" => Time.parse(range[:from]),
388
- "to" => Time.parse(range[:to])
389
- }
390
- end
391
- end
392
- assert_equal(expect, Lead.timeslice(from, to, count))
393
- end
394
- end
395
-
396
- private
397
-
398
- def request
399
- {
400
- lead_selector: {
401
- oldest_updated_at: timerange.first["from"].iso8601,
402
- latest_updated_at: timerange.first["to"].iso8601,
403
- },
404
- attributes!: {lead_selector: {"xsi:type"=>"ns1:LastUpdateAtSelector"}},
405
- batch_size: MarketoApi::Soap::Lead::BATCH_SIZE_DEFAULT,
406
- }
407
- end
408
- end
409
-
410
- class GuessTest < self
411
- setup :setup_soap
412
-
413
- def setup_soap
414
- @soap = MarketoApi::Soap::Lead.new(settings[:endpoint], settings[:wsdl], settings[:user_id], settings[:encryption_key])
415
-
416
- stub(Lead).soap_client(config) { @soap }
417
- end
418
-
419
- def test_include_metadata
420
- stub(@soap).metadata { metadata }
421
-
422
- assert_equal(
423
- {"columns" => expected_guessed_columns},
424
- Lead.guess(config)
425
- )
426
- end
427
-
428
- data do
429
- [
430
- ["endpoint", "endpoint"],
431
- ["wsdl", "wsdl"],
432
- ]
433
- end
434
- def test_invalid_url(key)
435
- config[key] = " invalid url "
436
- assert_raise(ConfigError) do
437
- Lead.guess(config)
438
- end
439
- end
440
- end
441
-
442
- def test_generate_columns
443
- assert_equal(expected_guessed_columns, Lead.generate_columns(metadata))
444
- end
445
-
446
- private
447
-
448
- def config
449
- DataSource[settings.to_a]
450
- end
451
-
452
- def settings
453
- {
454
- endpoint: "https://marketo.example.com",
455
- wsdl: "https://marketo.example.com/?wsdl",
456
- user_id: "user_id",
457
- encryption_key: "TOPSECRET",
458
- from_datetime: from_datetime,
459
- to_datetime: to_datetime,
460
- columns: [
461
- {"name" => "Name", "type" => "string"},
462
- ]
463
- }
464
- end
465
-
466
- def from_datetime
467
- "2015-07-01 00:00:00+00:00"
468
- end
469
-
470
- def to_datetime
471
- "2015-07-01 00:00:05+00:00"
472
- end
473
-
474
- def timerange
475
- Lead.generate_time_range(from_datetime, to_datetime)
476
- end
477
-
478
- def task
479
- # Values in Lead#timeslice are converted String from Time in
480
- # Embulk (.transaction -> #init),
481
- # but below values are passed to #init directly, so convert them.
482
- raw_timeslice = Lead.timeslice(from_datetime, to_datetime, Lead::TIMESLICE_COUNT_PER_TASK)
483
- timeslice = raw_timeslice.map do |ranges|
484
- ranges.map do |range|
485
- {"from" => range["from"].to_s, "to" => range["to"].to_s}
486
- end
487
- end
488
-
489
- {
490
- endpoint_url: "https://marketo.example.com",
491
- wsdl_url: "https://marketo.example.com/?wsdl",
492
- user_id: "user_id",
493
- encryption_key: "TOPSECRET",
494
- from_datetime: from_datetime,
495
- to_datetime: to_datetime,
496
- retry_initial_wait_sec: 0,
497
- retry_limit: 3,
498
- append_processed_time_column: true,
499
- ranges: timeslice,
500
- columns: [
501
- {"name" => "Name", "type" => "string"},
502
- ]
503
- }
504
- end
505
-
506
- def metadata
507
- [
508
- {
509
- name: "FieldName",
510
- description: nil,
511
- display_name: "The Name of Field",
512
- source_object: "Lead",
513
- data_type: "datetime",
514
- size: nil,
515
- is_readonly: false,
516
- is_update_blocked: false,
517
- is_name: nil,
518
- is_primary_key: false,
519
- is_custom: true,
520
- is_dynamic: true,
521
- dynamic_field_ref: "leadAttributeList",
522
- updated_at: DateTime.parse("2000-01-01 22:22:22")
523
- },
524
- {
525
- name: "FieldInt",
526
- description: nil,
527
- display_name: "The Name of Field",
528
- source_object: "Lead",
529
- data_type: "integer",
530
- size: nil,
531
- is_readonly: false,
532
- is_update_blocked: false,
533
- is_name: nil,
534
- is_primary_key: false,
535
- is_custom: true,
536
- is_dynamic: true,
537
- dynamic_field_ref: "leadAttributeList",
538
- updated_at: DateTime.parse("2000-01-01 22:22:22")
539
- },
540
- {
541
- name: "FieldBoolean",
542
- description: nil,
543
- display_name: "The Name of Field",
544
- source_object: "Lead",
545
- data_type: "boolean",
546
- size: nil,
547
- is_readonly: false,
548
- is_update_blocked: false,
549
- is_name: nil,
550
- is_primary_key: false,
551
- is_custom: true,
552
- is_dynamic: true,
553
- dynamic_field_ref: "leadAttributeList",
554
- updated_at: DateTime.parse("2000-01-01 22:22:22")
555
- },
556
- {
557
- name: "FieldFloat",
558
- description: nil,
559
- display_name: "The Name of Field",
560
- source_object: "Lead",
561
- data_type: "float",
562
- size: nil,
563
- is_readonly: false,
564
- is_update_blocked: false,
565
- is_name: nil,
566
- is_primary_key: false,
567
- is_custom: true,
568
- is_dynamic: true,
569
- dynamic_field_ref: "leadAttributeList",
570
- updated_at: DateTime.parse("2000-01-01 22:22:22")
571
- },
572
- {
573
- name: "FieldString",
574
- description: nil,
575
- display_name: "The Name of Field",
576
- source_object: "Lead",
577
- data_type: "string",
578
- size: nil,
579
- is_readonly: false,
580
- is_update_blocked: false,
581
- is_name: nil,
582
- is_primary_key: false,
583
- is_custom: true,
584
- is_dynamic: true,
585
- dynamic_field_ref: "leadAttributeList",
586
- updated_at: DateTime.parse("2000-01-01 22:22:22")
587
- }
588
- ]
589
- end
590
-
591
- def expected_guessed_columns
592
- [
593
- {name: "id", type: "long"},
594
- {name: "email", type: "string"},
595
- {name: "FieldName", type: "timestamp"},
596
- {name: "FieldInt", type: "long"},
597
- {name: "FieldBoolean", type: "boolean"},
598
- {name: "FieldFloat", type: "double"},
599
- {name: "FieldString", type: "string"},
600
- ]
601
- end
602
- end
603
- end
604
- end
605
- end