embulk-input-marketo 0.0.1 → 0.1.0
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 +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +25 -6
- data/Rakefile +53 -1
- data/embulk-input-marketo.gemspec +1 -1
- data/lib/embulk/input/marketo/activity_log.rb +55 -0
- data/lib/embulk/input/marketo/base.rb +89 -0
- data/lib/embulk/input/marketo/lead.rb +73 -0
- data/lib/embulk/input/marketo_api.rb +14 -3
- data/lib/embulk/input/marketo_api/soap/activity_log.rb +90 -0
- data/lib/embulk/input/marketo_api/soap/base.rb +55 -0
- data/lib/embulk/input/marketo_api/soap/lead.rb +75 -0
- data/test/activity_log_fixtures.rb +155 -0
- data/test/embulk/input/marketo/test_activity_log.rb +201 -0
- data/test/embulk/input/marketo/test_base.rb +63 -0
- data/test/embulk/input/marketo/test_lead.rb +172 -0
- data/test/embulk/input/marketo_api/soap/test_activity_log.rb +109 -0
- data/test/embulk/input/marketo_api/soap/test_base.rb +43 -0
- data/test/embulk/input/marketo_api/soap/test_lead.rb +110 -0
- data/test/embulk/input/test_marketo_api.rb +28 -0
- metadata +24 -8
- data/lib/embulk/input/marketo.rb +0 -138
- data/lib/embulk/input/marketo_api/soap.rb +0 -112
- data/test/embulk/input/marketo_api/test_soap.rb +0 -123
- data/test/embulk/input/test_marketo.rb +0 -176
@@ -0,0 +1,63 @@
|
|
1
|
+
require "prepare_embulk"
|
2
|
+
require "embulk/input/marketo/base"
|
3
|
+
|
4
|
+
module Embulk
|
5
|
+
module Input
|
6
|
+
module Marketo
|
7
|
+
class BaseTest < Test::Unit::TestCase
|
8
|
+
def test_target
|
9
|
+
assert_raise(NotImplementedError) do
|
10
|
+
Base.target
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_transaction
|
15
|
+
control = proc {} # dummy
|
16
|
+
columns = task[:columns].map do |col|
|
17
|
+
Column.new(nil, col["name"], col["type"].to_sym)
|
18
|
+
end
|
19
|
+
|
20
|
+
mock(Base).resume(task, columns, 1, &control)
|
21
|
+
Base.transaction(config, &control)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def config
|
27
|
+
DataSource[settings.to_a]
|
28
|
+
end
|
29
|
+
|
30
|
+
def settings
|
31
|
+
{
|
32
|
+
endpoint: "https://marketo.example.com",
|
33
|
+
wsdl: "https://marketo.example.com/?wsdl",
|
34
|
+
user_id: "user_id",
|
35
|
+
encryption_key: "TOPSECRET",
|
36
|
+
last_updated_at: last_updated_at,
|
37
|
+
columns: [
|
38
|
+
{"name" => "Name", "type" => "string"},
|
39
|
+
]
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def last_updated_at
|
44
|
+
"2015-07-01 00:00:00+00:00"
|
45
|
+
end
|
46
|
+
|
47
|
+
def task
|
48
|
+
{
|
49
|
+
endpoint_url: "https://marketo.example.com",
|
50
|
+
wsdl_url: "https://marketo.example.com/?wsdl",
|
51
|
+
user_id: "user_id",
|
52
|
+
encryption_key: "TOPSECRET",
|
53
|
+
last_updated_at: last_updated_at,
|
54
|
+
columns: [
|
55
|
+
{"name" => "Name", "type" => "string"},
|
56
|
+
]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require "prepare_embulk"
|
2
|
+
require "lead_fixtures"
|
3
|
+
require "embulk/input/marketo/lead"
|
4
|
+
|
5
|
+
module Embulk
|
6
|
+
module Input
|
7
|
+
module Marketo
|
8
|
+
class LeadTest < Test::Unit::TestCase
|
9
|
+
include LeadFixtures
|
10
|
+
|
11
|
+
def test_target
|
12
|
+
assert_equal(:lead, Lead.target)
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup_soap
|
16
|
+
@soap = MarketoApi::Soap::Lead.new(settings[:endpoint], settings[:wsdl], settings[:user_id], settings[:encryption_key])
|
17
|
+
|
18
|
+
stub(Lead).soap_client(task) { @soap }
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup_plugin
|
22
|
+
@page_builder = Object.new
|
23
|
+
@plugin = Lead.new(task, nil, nil, @page_builder)
|
24
|
+
stub(Embulk).logger { ::Logger.new(File::NULL) }
|
25
|
+
end
|
26
|
+
|
27
|
+
class RunTest < self
|
28
|
+
def setup
|
29
|
+
setup_soap
|
30
|
+
setup_plugin
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_run_through
|
34
|
+
stub(@plugin).preview? { false }
|
35
|
+
|
36
|
+
any_instance_of(Savon::Client) do |klass|
|
37
|
+
mock(klass).call(:get_multiple_leads, message: request) do
|
38
|
+
leads_response
|
39
|
+
end
|
40
|
+
|
41
|
+
mock(klass).call(:get_multiple_leads, message: request.merge(stream_position: stream_position)) do
|
42
|
+
next_stream_leads_response
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
mock(@page_builder).add(["manyo"])
|
47
|
+
mock(@page_builder).add(["everyleaf"])
|
48
|
+
mock(@page_builder).add(["ten-thousand-leaf"])
|
49
|
+
mock(@page_builder).finish
|
50
|
+
|
51
|
+
@plugin.run
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_preview_through
|
55
|
+
stub(@plugin).preview? { true }
|
56
|
+
|
57
|
+
any_instance_of(Savon::Client) do |klass|
|
58
|
+
mock(klass).call(:get_multiple_leads, message: request) do
|
59
|
+
preview_leads_response
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
Lead::PREVIEW_COUNT.times do |count|
|
64
|
+
mock(@page_builder).add(["manyo#{count}"])
|
65
|
+
end
|
66
|
+
mock(@page_builder).finish
|
67
|
+
|
68
|
+
@plugin.run
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def request
|
74
|
+
{
|
75
|
+
lead_selector: {oldest_updated_at: Time.parse(last_updated_at).iso8601},
|
76
|
+
attributes!: {lead_selector: {"xsi:type"=>"ns1:LastUpdateAtSelector"}},
|
77
|
+
batch_size: 1000
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class GuessTest < self
|
83
|
+
setup :setup_soap
|
84
|
+
|
85
|
+
def setup_soap
|
86
|
+
@soap = MarketoApi::Soap::Lead.new(settings[:endpoint], settings[:wsdl], settings[:user_id], settings[:encryption_key])
|
87
|
+
|
88
|
+
stub(Lead).soap_client(config) { @soap }
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_include_metadata
|
92
|
+
stub(@soap).metadata { metadata }
|
93
|
+
|
94
|
+
assert_equal(
|
95
|
+
{"columns" => expected_guessed_columns},
|
96
|
+
Lead.guess(config)
|
97
|
+
)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_generate_columns
|
102
|
+
assert_equal(expected_guessed_columns, Lead.generate_columns(metadata))
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def config
|
108
|
+
DataSource[settings.to_a]
|
109
|
+
end
|
110
|
+
|
111
|
+
def settings
|
112
|
+
{
|
113
|
+
endpoint: "https://marketo.example.com",
|
114
|
+
wsdl: "https://marketo.example.com/?wsdl",
|
115
|
+
user_id: "user_id",
|
116
|
+
encryption_key: "TOPSECRET",
|
117
|
+
last_updated_at: last_updated_at,
|
118
|
+
columns: [
|
119
|
+
{"name" => "Name", "type" => "string"},
|
120
|
+
]
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
def last_updated_at
|
125
|
+
"2015-07-01 00:00:00+00:00"
|
126
|
+
end
|
127
|
+
|
128
|
+
def task
|
129
|
+
{
|
130
|
+
endpoint_url: "https://marketo.example.com",
|
131
|
+
wsdl_url: "https://marketo.example.com/?wsdl",
|
132
|
+
user_id: "user_id",
|
133
|
+
encryption_key: "TOPSECRET",
|
134
|
+
last_updated_at: last_updated_at,
|
135
|
+
columns: [
|
136
|
+
{"name" => "Name", "type" => "string"},
|
137
|
+
]
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
def metadata
|
142
|
+
[
|
143
|
+
{
|
144
|
+
name: "FieldName",
|
145
|
+
description: nil,
|
146
|
+
display_name: "The Name of Field",
|
147
|
+
source_object: "Lead",
|
148
|
+
data_type: "datetime",
|
149
|
+
size: nil,
|
150
|
+
is_readonly: false,
|
151
|
+
is_update_blocked: false,
|
152
|
+
is_name: nil,
|
153
|
+
is_primary_key: false,
|
154
|
+
is_custom: true,
|
155
|
+
is_dynamic: true,
|
156
|
+
dynamic_field_ref: "leadAttributeList",
|
157
|
+
updated_at: DateTime.parse("2000-01-01 22:22:22")
|
158
|
+
}
|
159
|
+
]
|
160
|
+
end
|
161
|
+
|
162
|
+
def expected_guessed_columns
|
163
|
+
[
|
164
|
+
{name: "id", type: "long"},
|
165
|
+
{name: "email", type: "string"},
|
166
|
+
{name: "FieldName", type: "string"},
|
167
|
+
]
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require "embulk/input/marketo_api/soap/activity_log"
|
2
|
+
require "activity_log_fixtures"
|
3
|
+
|
4
|
+
module Embulk
|
5
|
+
module Input
|
6
|
+
module MarketoApi
|
7
|
+
module Soap
|
8
|
+
class ActivityLogTest < Test::Unit::TestCase
|
9
|
+
include ActivityLogFixtures
|
10
|
+
|
11
|
+
def setup
|
12
|
+
stub(Embulk).logger { ::Logger.new(IO::NULL) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_each
|
16
|
+
request = {
|
17
|
+
start_position: {
|
18
|
+
oldest_created_at: Time.parse(last_updated_at).iso8601,
|
19
|
+
},
|
20
|
+
batch_size: 100
|
21
|
+
}
|
22
|
+
|
23
|
+
any_instance_of(Savon::Client) do |klass|
|
24
|
+
mock(klass).call(:get_lead_changes, message: request) do
|
25
|
+
next_stream_activity_logs_response
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
proc = proc{ "" }
|
30
|
+
activity_log_count = next_stream_activity_logs_response[:body][:success_get_lead_changes][:result][:lead_change_record_list][:lead_change_record].size
|
31
|
+
|
32
|
+
mock(proc).call(anything).times(activity_log_count)
|
33
|
+
|
34
|
+
soap.each(last_updated_at, &proc)
|
35
|
+
end
|
36
|
+
|
37
|
+
class TestMetadata < self
|
38
|
+
def setup
|
39
|
+
super
|
40
|
+
|
41
|
+
@savon = soap.__send__(:savon)
|
42
|
+
stub(soap).savon { @savon } # Pin savon instance for each call soap.savon for mocking/stubbing
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_savon_call
|
46
|
+
mock(@savon).call(:get_lead_changes, message: request) {
|
47
|
+
next_stream_activity_logs_response
|
48
|
+
}
|
49
|
+
soap.metadata(last_updated_at)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_return_schema
|
53
|
+
stub(@savon).call(:get_lead_changes, message: request) {
|
54
|
+
next_stream_activity_logs_response
|
55
|
+
}
|
56
|
+
assert_equal(schema, soap.metadata(last_updated_at))
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def request
|
62
|
+
{
|
63
|
+
start_position: {
|
64
|
+
oldest_created_at: Time.parse(last_updated_at).iso8601,
|
65
|
+
},
|
66
|
+
batch_size: 100
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def schema
|
71
|
+
metadata = [
|
72
|
+
{index: 0, name: "id", type: :long},
|
73
|
+
{index: 1, name: "activity_date_time", type: :timestamp, format: "%Y-%m-%d %H:%M:%S %z"},
|
74
|
+
{index: 2, name: "activity_type", type: :string},
|
75
|
+
{index: 3, name: "mktg_asset_name", type: :string},
|
76
|
+
{index: 4, name: "mkt_person_id", type: :long},
|
77
|
+
{index: 5, name: "Attribute Name", type: :string},
|
78
|
+
{index: 6, name: "Old Value", type: :long},
|
79
|
+
]
|
80
|
+
|
81
|
+
metadata.map do |column|
|
82
|
+
Column.new(column)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def last_updated_at
|
90
|
+
"2015-07-06"
|
91
|
+
end
|
92
|
+
|
93
|
+
def soap
|
94
|
+
@soap ||= ActivityLog.new(settings[:endpoint], settings[:wsdl], settings[:user_id], settings[:encryption_key])
|
95
|
+
end
|
96
|
+
|
97
|
+
def settings
|
98
|
+
{
|
99
|
+
endpoint: "https://marketo.example.com",
|
100
|
+
wsdl: "https://marketo.example.com/?wsdl",
|
101
|
+
user_id: "user_id",
|
102
|
+
encryption_key: "TOPSECRET",
|
103
|
+
}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "embulk/input/marketo_api/soap/base"
|
2
|
+
require "lead_fixtures"
|
3
|
+
|
4
|
+
module Embulk
|
5
|
+
module Input
|
6
|
+
module MarketoApi
|
7
|
+
module Soap
|
8
|
+
class BaseTest < Test::Unit::TestCase
|
9
|
+
include LeadFixtures
|
10
|
+
|
11
|
+
class TestSignature < self
|
12
|
+
def setup
|
13
|
+
@signature = soap.__send__(:signature)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_sigature_keys
|
17
|
+
assert_equal(%w(requestTimestamp requestSignature).sort, @signature.keys.sort)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_is_hash
|
21
|
+
assert_equal(Hash, @signature.class)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def soap
|
28
|
+
@soap ||= Base.new(settings[:endpoint], settings[:wsdl], settings[:user_id], settings[:encryption_key])
|
29
|
+
end
|
30
|
+
|
31
|
+
def settings
|
32
|
+
{
|
33
|
+
endpoint: "https://marketo.example.com",
|
34
|
+
wsdl: "https://marketo.example.com/?wsdl",
|
35
|
+
user_id: "user_id",
|
36
|
+
encryption_key: "TOPSECRET",
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require "embulk/input/marketo_api/soap/lead"
|
2
|
+
require "lead_fixtures"
|
3
|
+
|
4
|
+
module Embulk
|
5
|
+
module Input
|
6
|
+
module MarketoApi
|
7
|
+
module Soap
|
8
|
+
class LeadTest < Test::Unit::TestCase
|
9
|
+
include LeadFixtures
|
10
|
+
|
11
|
+
def test_each
|
12
|
+
stub(Embulk).logger { ::Logger.new(IO::NULL) }
|
13
|
+
last_updated_at = "2015-07-06"
|
14
|
+
|
15
|
+
request = {
|
16
|
+
lead_selector: {oldest_updated_at: Time.parse(last_updated_at).iso8601},
|
17
|
+
attributes!: {lead_selector: {"xsi:type"=>"ns1:LastUpdateAtSelector"}},
|
18
|
+
batch_size: 1000
|
19
|
+
}
|
20
|
+
|
21
|
+
any_instance_of(Savon::Client) do |klass|
|
22
|
+
mock(klass).call(:get_multiple_leads, message: request) do
|
23
|
+
next_stream_leads_response
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
proc = proc{ "" }
|
28
|
+
leads_count = next_stream_leads_response.xpath('//leadRecord').length
|
29
|
+
mock(proc).call(anything).times(leads_count)
|
30
|
+
|
31
|
+
soap.each(last_updated_at, &proc)
|
32
|
+
end
|
33
|
+
|
34
|
+
class TestMetadata < self
|
35
|
+
def setup
|
36
|
+
@savon = soap.__send__(:savon)
|
37
|
+
stub(soap).savon { @savon } # Pin savon instance for each call soap.savon for mocking/stubbing
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_savon_call
|
41
|
+
mock(@savon).call(:describe_m_object, message: {object_name: "LeadRecord"}) {
|
42
|
+
Struct.new(:body).new(body)
|
43
|
+
}
|
44
|
+
soap.metadata
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_return_fields
|
48
|
+
stub(@savon).call(:describe_m_object, message: {object_name: "LeadRecord"}) {
|
49
|
+
Struct.new(:body).new(body)
|
50
|
+
}
|
51
|
+
assert_equal(fields, soap.metadata)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def body
|
57
|
+
{
|
58
|
+
success_describe_m_object: {
|
59
|
+
result: {
|
60
|
+
metadata: {
|
61
|
+
field_list: {
|
62
|
+
field: fields
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def fields
|
71
|
+
[
|
72
|
+
{
|
73
|
+
name: "FieldName",
|
74
|
+
description: nil,
|
75
|
+
display_name: "The Name of Field",
|
76
|
+
source_object: "Lead",
|
77
|
+
data_type: "datetime",
|
78
|
+
size: nil,
|
79
|
+
is_readonly: false,
|
80
|
+
is_update_blocked: false,
|
81
|
+
is_name: nil,
|
82
|
+
is_primary_key: false,
|
83
|
+
is_custom: true,
|
84
|
+
is_dynamic: true,
|
85
|
+
dynamic_field_ref: "leadAttributeList",
|
86
|
+
updated_at: DateTime.parse("2000-01-01 22:22:22")
|
87
|
+
}
|
88
|
+
]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def soap
|
95
|
+
@soap ||= Lead.new(settings[:endpoint], settings[:wsdl], settings[:user_id], settings[:encryption_key])
|
96
|
+
end
|
97
|
+
|
98
|
+
def settings
|
99
|
+
{
|
100
|
+
endpoint: "https://marketo.example.com",
|
101
|
+
wsdl: "https://marketo.example.com/?wsdl",
|
102
|
+
user_id: "user_id",
|
103
|
+
encryption_key: "TOPSECRET",
|
104
|
+
}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|