embulk-input-marketo_extended 0.6.18

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 (88) hide show
  1. checksums.yaml +7 -0
  2. data/.github/PULL_REQUEST_TEMPLATE.md +37 -0
  3. data/.gitignore +14 -0
  4. data/.travis.yml +6 -0
  5. data/CHANGELOG.md +170 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +213 -0
  8. data/build.gradle +103 -0
  9. data/config/checkstyle/checkstyle.xml +128 -0
  10. data/config/checkstyle/default.xml +108 -0
  11. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  12. data/gradle/wrapper/gradle-wrapper.properties +6 -0
  13. data/gradlew +169 -0
  14. data/gradlew.bat +84 -0
  15. data/lib/embulk/input/marketo.rb +3 -0
  16. data/settings.gradle +1 -0
  17. data/src/main/java/org/embulk/input/marketo/CsvTokenizer.java +700 -0
  18. data/src/main/java/org/embulk/input/marketo/MarketoInputPlugin.java +15 -0
  19. data/src/main/java/org/embulk/input/marketo/MarketoInputPluginDelegate.java +100 -0
  20. data/src/main/java/org/embulk/input/marketo/MarketoService.java +38 -0
  21. data/src/main/java/org/embulk/input/marketo/MarketoServiceImpl.java +245 -0
  22. data/src/main/java/org/embulk/input/marketo/MarketoUtils.java +212 -0
  23. data/src/main/java/org/embulk/input/marketo/delegate/ActivityBulkExtractInputPlugin.java +167 -0
  24. data/src/main/java/org/embulk/input/marketo/delegate/CampaignInputPlugin.java +48 -0
  25. data/src/main/java/org/embulk/input/marketo/delegate/CustomObjectInputPlugin.java +75 -0
  26. data/src/main/java/org/embulk/input/marketo/delegate/CustomObjectResponseMapperBuilder.java +81 -0
  27. data/src/main/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPlugin.java +66 -0
  28. data/src/main/java/org/embulk/input/marketo/delegate/LeadServiceResponseMapperBuilder.java +85 -0
  29. data/src/main/java/org/embulk/input/marketo/delegate/LeadWithListInputPlugin.java +64 -0
  30. data/src/main/java/org/embulk/input/marketo/delegate/LeadWithProgramInputPlugin.java +60 -0
  31. data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPlugin.java +441 -0
  32. data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseInputPluginDelegate.java +92 -0
  33. data/src/main/java/org/embulk/input/marketo/delegate/ProgramInputPlugin.java +228 -0
  34. data/src/main/java/org/embulk/input/marketo/exception/MarketoAPIException.java +30 -0
  35. data/src/main/java/org/embulk/input/marketo/model/BulkExtractRangeHeader.java +26 -0
  36. data/src/main/java/org/embulk/input/marketo/model/MarketoAccessTokenResponse.java +92 -0
  37. data/src/main/java/org/embulk/input/marketo/model/MarketoBulkExtractRequest.java +68 -0
  38. data/src/main/java/org/embulk/input/marketo/model/MarketoError.java +40 -0
  39. data/src/main/java/org/embulk/input/marketo/model/MarketoField.java +126 -0
  40. data/src/main/java/org/embulk/input/marketo/model/MarketoResponse.java +82 -0
  41. data/src/main/java/org/embulk/input/marketo/model/filter/DateRangeFilter.java +40 -0
  42. data/src/main/java/org/embulk/input/marketo/rest/MarketoBaseRestClient.java +306 -0
  43. data/src/main/java/org/embulk/input/marketo/rest/MarketoInputStreamResponseEntityReader.java +69 -0
  44. data/src/main/java/org/embulk/input/marketo/rest/MarketoRESTEndpoint.java +47 -0
  45. data/src/main/java/org/embulk/input/marketo/rest/MarketoResponseJetty92EntityReader.java +89 -0
  46. data/src/main/java/org/embulk/input/marketo/rest/MarketoRestClient.java +569 -0
  47. data/src/main/java/org/embulk/input/marketo/rest/RecordPagingIterable.java +180 -0
  48. data/src/test/java/org/embulk/input/marketo/MarketoServiceImplTest.java +140 -0
  49. data/src/test/java/org/embulk/input/marketo/MarketoUtilsTest.java +87 -0
  50. data/src/test/java/org/embulk/input/marketo/delegate/ActivityBulkExtractInputPluginTest.java +128 -0
  51. data/src/test/java/org/embulk/input/marketo/delegate/CampaignInputPluginTest.java +73 -0
  52. data/src/test/java/org/embulk/input/marketo/delegate/CustomObjectInputPluginTest.java +102 -0
  53. data/src/test/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPluginTest.java +99 -0
  54. data/src/test/java/org/embulk/input/marketo/delegate/LeadServiceResponseMapperBuilderTest.java +119 -0
  55. data/src/test/java/org/embulk/input/marketo/delegate/LeadWithListInputPluginTest.java +101 -0
  56. data/src/test/java/org/embulk/input/marketo/delegate/LeadWithProgramInputPluginTest.java +103 -0
  57. data/src/test/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPluginTest.java +169 -0
  58. data/src/test/java/org/embulk/input/marketo/delegate/ProgramInputPluginTest.java +343 -0
  59. data/src/test/java/org/embulk/input/marketo/rest/MarketoBaseRestClientTest.java +368 -0
  60. data/src/test/java/org/embulk/input/marketo/rest/MarketoRestClientTest.java +584 -0
  61. data/src/test/resources/config/activity_bulk_extract_config.yaml +7 -0
  62. data/src/test/resources/config/custom_object_config.yaml +8 -0
  63. data/src/test/resources/config/lead_bulk_extract_config.yaml +8 -0
  64. data/src/test/resources/config/rest_config.yaml +3 -0
  65. data/src/test/resources/fixtures/activity_extract1.csv +35 -0
  66. data/src/test/resources/fixtures/activity_extract2.csv +22 -0
  67. data/src/test/resources/fixtures/activity_types.json +22 -0
  68. data/src/test/resources/fixtures/all_program_full.json +53 -0
  69. data/src/test/resources/fixtures/campaign_response.json +38 -0
  70. data/src/test/resources/fixtures/campaign_response_full.json +102 -0
  71. data/src/test/resources/fixtures/custom_object_describe.json +124 -0
  72. data/src/test/resources/fixtures/custom_object_describe_marketo_fields_full.json +22 -0
  73. data/src/test/resources/fixtures/custom_object_expected.json +66 -0
  74. data/src/test/resources/fixtures/custom_object_response.json +24 -0
  75. data/src/test/resources/fixtures/custom_object_response_full.json +23 -0
  76. data/src/test/resources/fixtures/lead_by_list.json +33 -0
  77. data/src/test/resources/fixtures/lead_by_program_response.json +47 -0
  78. data/src/test/resources/fixtures/lead_describe.json +221 -0
  79. data/src/test/resources/fixtures/lead_describe_expected.json +66 -0
  80. data/src/test/resources/fixtures/lead_describe_marketo_fields_full.json +518 -0
  81. data/src/test/resources/fixtures/lead_extract1.csv +11 -0
  82. data/src/test/resources/fixtures/lead_response_full.json +2402 -0
  83. data/src/test/resources/fixtures/lead_with_program_full.json +17 -0
  84. data/src/test/resources/fixtures/leads_extract2.csv +10 -0
  85. data/src/test/resources/fixtures/list_reponse_full.json +191 -0
  86. data/src/test/resources/fixtures/lists_response.json +31 -0
  87. data/src/test/resources/fixtures/program_response.json +71 -0
  88. metadata +171 -0
@@ -0,0 +1,368 @@
1
+ package org.embulk.input.marketo.rest;
2
+
3
+ import com.google.common.base.Optional;
4
+ import com.google.common.collect.ImmutableListMultimap;
5
+ import com.google.common.collect.Lists;
6
+ import com.google.common.collect.Maps;
7
+ import com.google.common.collect.Multimap;
8
+ import org.eclipse.jetty.client.HttpClient;
9
+ import org.eclipse.jetty.client.HttpResponseException;
10
+ import org.eclipse.jetty.client.api.ContentProvider;
11
+ import org.eclipse.jetty.client.api.Request;
12
+ import org.eclipse.jetty.client.api.Response;
13
+ import org.eclipse.jetty.client.util.StringContentProvider;
14
+ import org.eclipse.jetty.http.HttpMethod;
15
+ import org.embulk.EmbulkTestRuntime;
16
+ import org.embulk.config.ConfigException;
17
+ import org.embulk.input.marketo.exception.MarketoAPIException;
18
+ import org.embulk.input.marketo.model.MarketoError;
19
+ import org.embulk.input.marketo.model.MarketoResponse;
20
+ import org.embulk.spi.DataException;
21
+ import org.embulk.util.retryhelper.jetty92.Jetty92ClientCreator;
22
+ import org.embulk.util.retryhelper.jetty92.Jetty92RetryHelper;
23
+ import org.embulk.util.retryhelper.jetty92.Jetty92SingleRequester;
24
+ import org.embulk.util.retryhelper.jetty92.StringJetty92ResponseEntityReader;
25
+ import org.junit.Assert;
26
+ import org.junit.Before;
27
+ import org.junit.Rule;
28
+ import org.junit.Test;
29
+ import org.junit.function.ThrowingRunnable;
30
+ import org.mockito.ArgumentCaptor;
31
+ import org.mockito.Mockito;
32
+
33
+ import java.io.EOFException;
34
+ import java.io.IOException;
35
+ import java.net.SocketTimeoutException;
36
+ import java.nio.charset.StandardCharsets;
37
+ import java.util.HashMap;
38
+ import java.util.Map;
39
+ import java.util.concurrent.ExecutionException;
40
+ import java.util.concurrent.TimeoutException;
41
+
42
+ /**
43
+ * Created by tai.khuu on 9/21/17.
44
+ */
45
+ public class MarketoBaseRestClientTest
46
+ {
47
+ private static final String IDENTITY_END_POINT = "identityEndPoint";
48
+
49
+ private static final int MARKETO_LIMIT_INTERVAL_MILIS = 1000;
50
+
51
+ private MarketoBaseRestClient marketoBaseRestClient;
52
+
53
+ private Jetty92RetryHelper mockJetty92;
54
+
55
+ @Rule
56
+ public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
57
+ @Before
58
+ public void prepare()
59
+ {
60
+ mockJetty92 = Mockito.mock(Jetty92RetryHelper.class);
61
+ marketoBaseRestClient = new MarketoBaseRestClient("identityEndPoint", "clientId", "clientSecret", Optional.<String>absent(), MARKETO_LIMIT_INTERVAL_MILIS, 60000, mockJetty92);
62
+ }
63
+
64
+ @Test
65
+ public void testGetAccessToken()
66
+ {
67
+ Mockito.when(mockJetty92.requestWithRetry(Mockito.any(StringJetty92ResponseEntityReader.class), Mockito.any(Jetty92SingleRequester.class))).thenReturn("{\n" +
68
+ " \"access_token\": \"access_token\",\n" +
69
+ " \"token_type\": \"bearer\",\n" +
70
+ " \"expires_in\": 3599,\n" +
71
+ " \"scope\": \"tai@treasure-data.com\"\n" +
72
+ "}");
73
+ String accessToken = marketoBaseRestClient.getAccessToken();
74
+ Assert.assertEquals("access_token", accessToken);
75
+ }
76
+
77
+ @Test
78
+ public void testGetAccessTokenRequester()
79
+ {
80
+ ArgumentCaptor<Jetty92SingleRequester> jetty92SingleRequesterArgumentCaptor = ArgumentCaptor.forClass(Jetty92SingleRequester.class);
81
+ Mockito.when(mockJetty92.requestWithRetry(Mockito.any(StringJetty92ResponseEntityReader.class), jetty92SingleRequesterArgumentCaptor.capture())).thenReturn("{\"access_token\": \"access_token\"}");
82
+ String accessToken = marketoBaseRestClient.getAccessToken();
83
+ Assert.assertEquals("access_token", accessToken);
84
+ Jetty92SingleRequester jetty92SingleRequester = jetty92SingleRequesterArgumentCaptor.getValue();
85
+ HttpClient client = Mockito.mock(HttpClient.class);
86
+ Response.Listener listener = Mockito.mock(Response.Listener.class);
87
+ Request mockRequest = Mockito.mock(Request.class);
88
+ Mockito.when(client.newRequest(Mockito.eq(IDENTITY_END_POINT + MarketoRESTEndpoint.ACCESS_TOKEN.getEndpoint()))).thenReturn(mockRequest);
89
+ Request request1 = Mockito.mock(Request.class);
90
+ Mockito.when(mockRequest.method(Mockito.eq(HttpMethod.GET))).thenReturn(request1);
91
+ jetty92SingleRequester.requestOnce(client, listener);
92
+ Mockito.verify(request1, Mockito.times(1)).param(Mockito.eq("client_id"), Mockito.eq("clientId"));
93
+ Mockito.verify(request1, Mockito.times(1)).param(Mockito.eq("client_secret"), Mockito.eq("clientSecret"));
94
+ Mockito.verify(request1, Mockito.times(1)).param(Mockito.eq("grant_type"), Mockito.eq("client_credentials"));
95
+
96
+ // By default the partner id is not set
97
+ Mockito.verify(request1, Mockito.never()).param(Mockito.eq("partner_id"), Mockito.anyString());
98
+
99
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createHttpResponseException(502)));
100
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new ExecutionException(new TimeoutException())));
101
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new ExecutionException(new EOFException())));
102
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new ExecutionException(new SocketTimeoutException())));
103
+ // Retry SocketTimeoutException, TimeoutException and EOFException
104
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new SocketTimeoutException()));
105
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new TimeoutException()));
106
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new EOFException()));
107
+ // When EOFException is wrapped in IOException it should be retried too
108
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new IOException(new EOFException())));
109
+ // Retry TimeoutException when it is wrapped in IOException
110
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new IOException(new TimeoutException())));
111
+ }
112
+
113
+ @Test
114
+ public void testGetAccessTokenRequestShouldHavePartnerId()
115
+ {
116
+ final String partnerId = "sample_partner_id";
117
+ mockJetty92 = Mockito.mock(Jetty92RetryHelper.class);
118
+ ArgumentCaptor<Jetty92SingleRequester> jetty92SingleRequesterArgumentCaptor = ArgumentCaptor.forClass(Jetty92SingleRequester.class);
119
+ Mockito.when(mockJetty92.requestWithRetry(Mockito.any(StringJetty92ResponseEntityReader.class), jetty92SingleRequesterArgumentCaptor.capture())).thenReturn("{\"access_token\": \"access_token\"}");
120
+
121
+ MarketoBaseRestClient restClient = Mockito.spy(new MarketoBaseRestClient("identityEndPoint",
122
+ "clientId",
123
+ "clientSecret",
124
+ Optional.of(partnerId),
125
+ MARKETO_LIMIT_INTERVAL_MILIS,
126
+ 60000,
127
+ mockJetty92));
128
+
129
+ // call method for evaluation
130
+ restClient.getAccessToken();
131
+
132
+ Jetty92SingleRequester singleRequester = jetty92SingleRequesterArgumentCaptor.getValue();
133
+
134
+ HttpClient client = Mockito.mock(HttpClient.class);
135
+ Request request = Mockito.mock(Request.class);
136
+
137
+ Request mockRequest = Mockito.mock(Request.class);
138
+ Mockito.when(client.newRequest(Mockito.eq(IDENTITY_END_POINT + MarketoRESTEndpoint.ACCESS_TOKEN.getEndpoint()))).thenReturn(mockRequest);
139
+ Mockito.when(mockRequest.method(Mockito.eq(HttpMethod.GET))).thenReturn(request);
140
+ singleRequester.requestOnce(client, Mockito.mock(Response.Listener.class));
141
+
142
+ Mockito.verify(request, Mockito.times(1)).param(Mockito.eq("client_id"), Mockito.eq("clientId"));
143
+ Mockito.verify(request, Mockito.times(1)).param(Mockito.eq("client_secret"), Mockito.eq("clientSecret"));
144
+ Mockito.verify(request, Mockito.times(1)).param(Mockito.eq("grant_type"), Mockito.eq("client_credentials"));
145
+ Mockito.verify(request, Mockito.times(1)).param(Mockito.eq("partner_id"), Mockito.eq(partnerId));
146
+ }
147
+
148
+ @Test
149
+ public void testGetAccessTokenWithError()
150
+ {
151
+ ArgumentCaptor<Jetty92SingleRequester> jetty92SingleRequesterArgumentCaptor = ArgumentCaptor.forClass(Jetty92SingleRequester.class);
152
+ Mockito.when(mockJetty92.requestWithRetry(Mockito.any(StringJetty92ResponseEntityReader.class), jetty92SingleRequesterArgumentCaptor.capture())).thenReturn("{\n" +
153
+ " \"error\": \"invalid_client\",\n" +
154
+ " \"error_description\": \"Bad client credentials\"\n" +
155
+ "}");
156
+ try {
157
+ marketoBaseRestClient.getAccessToken();
158
+ }
159
+ catch (DataException ex) {
160
+ Assert.assertEquals("Bad client credentials", ex.getMessage());
161
+ return;
162
+ }
163
+ Assert.fail();
164
+ }
165
+
166
+ @Test
167
+ public void testGetAccessTokenThrowHttpResponseException() throws Exception
168
+ {
169
+ HttpClient client = Mockito.mock(HttpClient.class);
170
+
171
+ Jetty92ClientCreator clientCreator = Mockito.mock(Jetty92ClientCreator.class);
172
+ Mockito.doReturn(client).when(clientCreator).createAndStart();
173
+
174
+ Request request = Mockito.mock(Request.class);
175
+ Mockito.doReturn(request).when(client).newRequest(Mockito.anyString());
176
+ Mockito.doReturn(request).when(request).method(HttpMethod.GET);
177
+
178
+ HttpResponseException exception = new HttpResponseException("{\"error\":\"invalid_client\",\"error_description\":\"Bad client credentials\"}", Mockito.mock(Response.class));
179
+ Mockito.doThrow(exception).when(request).send(Mockito.any(Response.Listener.class));
180
+
181
+ Jetty92RetryHelper retryHelper = new Jetty92RetryHelper(1, 1, 1, clientCreator);
182
+ final MarketoBaseRestClient restClient = new MarketoBaseRestClient("identityEndPoint", "clientId", "clientSecret", Optional.<String>absent(), MARKETO_LIMIT_INTERVAL_MILIS, 1000, retryHelper);
183
+
184
+ // calling method should wrap the HttpResponseException by ConfigException
185
+ Assert.assertThrows(ConfigException.class, new ThrowingRunnable()
186
+ {
187
+ @Override
188
+ public void run() throws Throwable
189
+ {
190
+ restClient.getAccessToken();
191
+ }
192
+ });
193
+ }
194
+
195
+ @Test
196
+ public void tetDoGetThrowHttpResponseException() throws Exception
197
+ {
198
+ final MarketoBaseRestClient client = doRequestWithWrapper(HttpMethod.GET);
199
+ // calling method should wrap the HttpResponseException by DataException
200
+ Assert.assertThrows(DataException.class, new ThrowingRunnable()
201
+ {
202
+ @Override
203
+ public void run() throws Throwable
204
+ {
205
+ client.doGet("test_target", null, null, new MarketoResponseJetty92EntityReader<String>(1000));
206
+ }
207
+ });
208
+ }
209
+
210
+ @Test
211
+ public void tetDoPostThrowHttpResponseException() throws Exception
212
+ {
213
+ final MarketoBaseRestClient client = doRequestWithWrapper(HttpMethod.POST);
214
+ // calling method should wrap the HttpResponseException by DataException
215
+ Assert.assertThrows(DataException.class, new ThrowingRunnable()
216
+ {
217
+ @Override
218
+ public void run() throws Throwable
219
+ {
220
+ client.doPost("test_target", null, null, "{\"any\": \"any\"}", new MarketoResponseJetty92EntityReader<String>(1000));
221
+ }
222
+ });
223
+ }
224
+
225
+ private MarketoBaseRestClient doRequestWithWrapper(HttpMethod method) throws Exception
226
+ {
227
+ HttpClient client = Mockito.mock(HttpClient.class);
228
+
229
+ Jetty92ClientCreator clientCreator = Mockito.mock(Jetty92ClientCreator.class);
230
+ Mockito.doReturn(client).when(clientCreator).createAndStart();
231
+
232
+ Request request = Mockito.mock(Request.class);
233
+ Mockito.doReturn(request).when(client).newRequest(Mockito.anyString());
234
+ Mockito.doReturn(request).when(request).method(method);
235
+
236
+ HttpResponseException exception = new HttpResponseException("{\"error\":\"1035\",\"error_description\":\"Unsupported filter type for target subscription: updatedAt\"}", Mockito.mock(Response.class));
237
+ Mockito.doThrow(exception).when(request).send(Mockito.any(Response.Listener.class));
238
+
239
+ Jetty92RetryHelper retryHelper = new Jetty92RetryHelper(1, 1, 1, clientCreator);
240
+ final MarketoBaseRestClient restClient = Mockito.spy(new MarketoBaseRestClient("identityEndPoint", "clientId", "clientSecret", Optional.<String>absent(), MARKETO_LIMIT_INTERVAL_MILIS, 1000, retryHelper));
241
+ Mockito.doReturn("test_access_token").when(restClient).getAccessToken();
242
+
243
+ return restClient;
244
+ }
245
+
246
+ @Test
247
+ public void testDoPost() throws Exception
248
+ {
249
+ MarketoBaseRestClient spy = Mockito.spy(marketoBaseRestClient);
250
+ spy.doPost("target", Maps.<String, String>newHashMap(), new ImmutableListMultimap.Builder<String, String>().build(), "test_content", new StringJetty92ResponseEntityReader(10));
251
+ Mockito.verify(spy, Mockito.times(1)).doRequest(Mockito.anyString(), Mockito.eq(HttpMethod.POST), Mockito.any(Map.class), Mockito.any(Multimap.class), Mockito.any(StringContentProvider.class), Mockito.any(StringJetty92ResponseEntityReader.class));
252
+ }
253
+
254
+ @Test
255
+ public void testDoGet() throws Exception
256
+ {
257
+ MarketoBaseRestClient spy = Mockito.spy(marketoBaseRestClient);
258
+ spy.doGet("target", Maps.<String, String>newHashMap(), new ImmutableListMultimap.Builder<String, String>().build(), new StringJetty92ResponseEntityReader(10));
259
+ Mockito.verify(spy, Mockito.times(1)).doRequest(Mockito.anyString(), Mockito.eq(HttpMethod.GET), Mockito.any(Map.class), Mockito.any(Multimap.class), Mockito.isNull(ContentProvider.class), Mockito.any(StringJetty92ResponseEntityReader.class));
260
+ }
261
+
262
+ @Test
263
+ public void testDoRequestRequester() throws Exception
264
+ {
265
+ MarketoBaseRestClient spy = Mockito.spy(marketoBaseRestClient);
266
+ StringContentProvider contentProvider = new StringContentProvider("Content", StandardCharsets.UTF_8);
267
+ ArgumentCaptor<Jetty92SingleRequester> jetty92SingleRequesterArgumentCaptor = ArgumentCaptor.forClass(Jetty92SingleRequester.class);
268
+
269
+ MarketoResponse<Object> expectedMarketoResponse = new MarketoResponse<>();
270
+
271
+ Mockito.when(mockJetty92.requestWithRetry(Mockito.any(MarketoResponseJetty92EntityReader.class), jetty92SingleRequesterArgumentCaptor.capture())).thenReturn(expectedMarketoResponse);
272
+ Mockito.when(mockJetty92.requestWithRetry(Mockito.any(StringJetty92ResponseEntityReader.class), Mockito.any(Jetty92SingleRequester.class))).thenReturn("{\"access_token\": \"access_token\"}");
273
+
274
+ String target = "target";
275
+ HashMap<String, String> headers = Maps.<String, String>newHashMap();
276
+ headers.put("testHeader1", "testHeaderValue1");
277
+
278
+ ImmutableListMultimap<String, String> build = new ImmutableListMultimap.Builder<String, String>().put("param", "param1").build();
279
+
280
+ MarketoResponse<Object> marketoResponse = spy.doRequest(target, HttpMethod.POST, headers, build, contentProvider, new MarketoResponseJetty92EntityReader<Object>(10));
281
+
282
+ HttpClient client = Mockito.mock(HttpClient.class);
283
+ Response.Listener listener = Mockito.mock(Response.Listener.class);
284
+ Request mockRequest = Mockito.mock(Request.class);
285
+ Mockito.when(client.newRequest(Mockito.eq(target))).thenReturn(mockRequest);
286
+
287
+ Mockito.when(mockRequest.method(Mockito.eq(HttpMethod.POST))).thenReturn(mockRequest);
288
+ Jetty92SingleRequester jetty92SingleRequester = jetty92SingleRequesterArgumentCaptor.getValue();
289
+ jetty92SingleRequester.requestOnce(client, listener);
290
+
291
+ Assert.assertEquals(expectedMarketoResponse, marketoResponse);
292
+
293
+ Mockito.verify(mockRequest, Mockito.times(1)).header(Mockito.eq("testHeader1"), Mockito.eq("testHeaderValue1"));
294
+ Mockito.verify(mockRequest, Mockito.times(1)).header(Mockito.eq("Authorization"), Mockito.eq("Bearer access_token"));
295
+ Mockito.verify(mockRequest, Mockito.times(1)).param(Mockito.eq("param"), Mockito.eq("param1"));
296
+ Mockito.verify(mockRequest, Mockito.times(1)).content(Mockito.eq(contentProvider));
297
+ }
298
+
299
+ @Test
300
+ public void testDoRequesterRetry() throws Exception
301
+ {
302
+ MarketoBaseRestClient spy = Mockito.spy(marketoBaseRestClient);
303
+ ArgumentCaptor<Jetty92SingleRequester> jetty92SingleRequesterArgumentCaptor = ArgumentCaptor.forClass(Jetty92SingleRequester.class);
304
+
305
+ Mockito.when(mockJetty92.requestWithRetry(Mockito.any(MarketoResponseJetty92EntityReader.class), jetty92SingleRequesterArgumentCaptor.capture())).thenReturn(new MarketoResponse<>());
306
+ Mockito.when(mockJetty92.requestWithRetry(Mockito.any(StringJetty92ResponseEntityReader.class), Mockito.any(Jetty92SingleRequester.class))).thenReturn("{\"access_token\": \"access_token\"}");
307
+
308
+ spy.doRequest("", HttpMethod.POST, null, null, null, new MarketoResponseJetty92EntityReader<Object>(10));
309
+
310
+ HttpClient client = Mockito.mock(HttpClient.class);
311
+ Response.Listener listener = Mockito.mock(Response.Listener.class);
312
+ Request mockRequest = Mockito.mock(Request.class);
313
+ Mockito.when(client.newRequest(Mockito.anyString())).thenReturn(mockRequest);
314
+
315
+ Mockito.when(mockRequest.method(Mockito.eq(HttpMethod.POST))).thenReturn(mockRequest);
316
+
317
+ Jetty92SingleRequester jetty92SingleRequester = jetty92SingleRequesterArgumentCaptor.getValue();
318
+ jetty92SingleRequester.requestOnce(client, listener);
319
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createHttpResponseException(502)));
320
+
321
+ Assert.assertFalse(jetty92SingleRequester.toRetry(createHttpResponseException(400)));
322
+
323
+ Assert.assertFalse(jetty92SingleRequester.toRetry(createMarketoAPIException("ERR", "ERR")));
324
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("606", "")));
325
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("615", "")));
326
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("602", "")));
327
+ // Should retry 601 error too
328
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("601", "")));
329
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("604", "")));
330
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("608", "")));
331
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("611", "")));
332
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("615", "")));
333
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("713", "")));
334
+ Assert.assertTrue(jetty92SingleRequester.toRetry(createMarketoAPIException("1029", "")));
335
+ // Retry wrap SocketTimeoutException, TimeoutException and EOFException
336
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new ExecutionException(new TimeoutException())));
337
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new ExecutionException(new EOFException())));
338
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new ExecutionException(new SocketTimeoutException())));
339
+ // When EOFException is wrapped in IOException it should be retried too
340
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new IOException(new EOFException())));
341
+ // Retry TimeoutException when it is wrapped in IOException
342
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new IOException(new TimeoutException())));
343
+
344
+ // Retry SocketTimeoutException, TimeoutException and EOFException
345
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new SocketTimeoutException()));
346
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new TimeoutException()));
347
+ Assert.assertTrue(jetty92SingleRequester.toRetry(new EOFException()));
348
+ // Call 3 times First call then 602 error and 601 error
349
+ Mockito.verify(mockJetty92, Mockito.times(3)).requestWithRetry(Mockito.any(StringJetty92ResponseEntityReader.class), Mockito.any(Jetty92SingleRequester.class));
350
+ }
351
+
352
+ private HttpResponseException createHttpResponseException(int statusCode)
353
+ {
354
+ HttpResponseException exception = Mockito.mock(HttpResponseException.class);
355
+ Response response = Mockito.mock(Response.class);
356
+ Mockito.when(exception.getResponse()).thenReturn(response);
357
+ Mockito.when(response.getStatus()).thenReturn(statusCode);
358
+ return exception;
359
+ }
360
+
361
+ private MarketoAPIException createMarketoAPIException(String code, String error)
362
+ {
363
+ MarketoError marketoError = new MarketoError();
364
+ marketoError.setCode(code);
365
+ marketoError.setMessage(error);
366
+ return new MarketoAPIException(Lists.newArrayList(marketoError));
367
+ }
368
+ }
@@ -0,0 +1,584 @@
1
+ package org.embulk.input.marketo.rest;
2
+
3
+ import com.fasterxml.jackson.databind.DeserializationFeature;
4
+ import com.fasterxml.jackson.databind.JavaType;
5
+ import com.fasterxml.jackson.databind.ObjectMapper;
6
+ import com.fasterxml.jackson.databind.node.ArrayNode;
7
+ import com.fasterxml.jackson.databind.node.ObjectNode;
8
+ import com.fasterxml.jackson.databind.node.TextNode;
9
+ import com.google.common.collect.ImmutableListMultimap;
10
+ import com.google.common.collect.Multimap;
11
+ import com.google.common.io.ByteStreams;
12
+ import org.eclipse.jetty.client.api.ContentProvider;
13
+ import org.eclipse.jetty.client.util.FormContentProvider;
14
+ import org.embulk.EmbulkTestRuntime;
15
+ import org.embulk.config.ConfigSource;
16
+ import org.embulk.input.marketo.MarketoUtils;
17
+ import org.embulk.input.marketo.model.MarketoError;
18
+ import org.embulk.input.marketo.model.MarketoField;
19
+ import org.embulk.input.marketo.model.MarketoResponse;
20
+ import org.embulk.spi.DataException;
21
+ import org.embulk.util.retryhelper.jetty92.Jetty92ResponseReader;
22
+ import org.embulk.util.retryhelper.jetty92.Jetty92RetryHelper;
23
+ import org.joda.time.DateTime;
24
+ import org.joda.time.format.DateTimeFormat;
25
+ import org.joda.time.format.DateTimeFormatter;
26
+ import org.junit.Assert;
27
+ import org.junit.Before;
28
+ import org.junit.Rule;
29
+ import org.junit.Test;
30
+ import org.mockito.ArgumentCaptor;
31
+ import org.mockito.ArgumentMatchers;
32
+ import org.mockito.Mockito;
33
+
34
+ import java.io.IOException;
35
+ import java.io.InputStream;
36
+ import java.nio.ByteBuffer;
37
+ import java.text.SimpleDateFormat;
38
+ import java.util.ArrayList;
39
+ import java.util.Arrays;
40
+ import java.util.Date;
41
+ import java.util.HashMap;
42
+ import java.util.Iterator;
43
+ import java.util.List;
44
+ import java.util.Map;
45
+
46
+ /**
47
+ * Created by khuutantaitai on 10/3/17.
48
+ */
49
+ public class MarketoRestClientTest
50
+ {
51
+ private static final String TEST_ACCOUNT_ID = "test_account_id";
52
+
53
+ private static final String TEST_CLIENT_SECRET = "test_client_secret";
54
+
55
+ private static final String TEST_CLIENT_ID = "test_client_id";
56
+
57
+ private static final String END_POINT = MarketoUtils.getEndPoint(TEST_ACCOUNT_ID);
58
+
59
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
60
+
61
+ @Rule
62
+ public EmbulkTestRuntime embulkTestRuntime = new EmbulkTestRuntime();
63
+
64
+ private MarketoRestClient marketoRestClient;
65
+
66
+ private Jetty92RetryHelper mockRetryHelper;
67
+
68
+ private static final JavaType RESPONSE_TYPE = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(MarketoResponse.class, MarketoResponse.class, ObjectNode.class);
69
+
70
+ @Before
71
+ public void prepare()
72
+ {
73
+ ConfigSource configSource = embulkTestRuntime.getExec().newConfigSource();
74
+ configSource.set("account_id", TEST_ACCOUNT_ID);
75
+ configSource.set("client_secret", TEST_CLIENT_SECRET);
76
+ configSource.set("client_id", TEST_CLIENT_ID);
77
+ configSource.set("max_return", 2);
78
+ MarketoRestClient.PluginTask task = configSource.loadConfig(MarketoRestClient.PluginTask.class);
79
+ mockRetryHelper = Mockito.mock(Jetty92RetryHelper.class);
80
+ MarketoRestClient realRestClient = new MarketoRestClient(task);
81
+ marketoRestClient = Mockito.spy(realRestClient);
82
+ }
83
+
84
+ @Test
85
+ public void describeLead() throws Exception
86
+ {
87
+ String leadSchema = new String(ByteStreams.toByteArray(this.getClass().getResourceAsStream("/fixtures/lead_describe.json")));
88
+ MarketoResponse<ObjectNode> marketoResponse = OBJECT_MAPPER.readValue(leadSchema, RESPONSE_TYPE);
89
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.DESCRIBE_LEAD.getEndpoint()), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
90
+ List<MarketoField> marketoFields = marketoRestClient.describeLead();
91
+ Assert.assertEquals(16, marketoFields.size());
92
+ JavaType marketoFieldType = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, MarketoField.class);
93
+ List<MarketoField> expectedFields = OBJECT_MAPPER.readValue(new String(ByteStreams.toByteArray(this.getClass().getResourceAsStream("/fixtures/lead_describe_expected.json"))), marketoFieldType);
94
+ Assert.assertArrayEquals(expectedFields.toArray(), marketoFields.toArray());
95
+ }
96
+
97
+ @Test
98
+ public void createLeadBulkExtract() throws Exception
99
+ {
100
+ MarketoResponse<ObjectNode> marketoResponse = new MarketoResponse<>();
101
+ marketoResponse.setSuccess(true);
102
+ Date startDate = new Date(1506865856000L);
103
+ Date endDate = new Date(1507297856000L);
104
+ ObjectNode bulkExtractResult = OBJECT_MAPPER.createObjectNode();
105
+ bulkExtractResult.set("exportId", new TextNode("bulkExtractId"));
106
+ marketoResponse.setResult(Arrays.asList(bulkExtractResult));
107
+ ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
108
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.CREATE_LEAD_EXTRACT.getEndpoint()), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), argumentCaptor.capture(), Mockito.any(MarketoResponseJetty92EntityReader.class));
109
+ String filterField = "filterField";
110
+ String bulkExtractId = marketoRestClient.createLeadBulkExtract(startDate, endDate, Arrays.asList("extract_field1", "extract_field2"), filterField);
111
+ Assert.assertEquals("bulkExtractId", bulkExtractId);
112
+ String postContent = argumentCaptor.getValue();
113
+ ObjectNode marketoBulkExtractRequest = (ObjectNode) OBJECT_MAPPER.readTree(postContent);
114
+ ObjectNode filter = (ObjectNode) marketoBulkExtractRequest.get("filter");
115
+ ObjectNode dateRangeFilter = (ObjectNode) filter.get(filterField);
116
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(MarketoUtils.MARKETO_DATE_SIMPLE_DATE_FORMAT);
117
+ Assert.assertEquals(simpleDateFormat.format(startDate), dateRangeFilter.get("startAt").textValue());
118
+ Assert.assertEquals(simpleDateFormat.format(endDate), dateRangeFilter.get("endAt").textValue());
119
+ Assert.assertEquals("CSV", marketoBulkExtractRequest.get("format").textValue());
120
+ ArrayNode fields = (ArrayNode) marketoBulkExtractRequest.get("fields");
121
+ Assert.assertEquals("extract_field1", fields.get(0).textValue());
122
+ Assert.assertEquals("extract_field2", fields.get(1).textValue());
123
+ }
124
+
125
+ @Test
126
+ public void createLeadBulkExtractWithError() throws Exception
127
+ {
128
+ MarketoResponse<ObjectNode> marketoResponse = new MarketoResponse<>();
129
+ marketoResponse.setSuccess(false);
130
+ MarketoError marketoError = new MarketoError();
131
+ marketoError.setCode("ErrorCode1");
132
+ marketoError.setMessage("Message");
133
+ marketoResponse.setErrors(Arrays.asList(marketoError));
134
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.CREATE_LEAD_EXTRACT.getEndpoint()), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.anyString(), Mockito.any(MarketoResponseJetty92EntityReader.class));
135
+ String filterField = "filterField";
136
+ try {
137
+ marketoRestClient.createLeadBulkExtract(new Date(), new Date(), Arrays.asList("extract_field1", "extract_field2"), filterField);
138
+ }
139
+ catch (DataException ex) {
140
+ Assert.assertEquals("ErrorCode1: Message", ex.getMessage());
141
+ return;
142
+ }
143
+ Assert.fail();
144
+ }
145
+
146
+ @Test
147
+ public void createActitvityExtract() throws Exception
148
+ {
149
+ MarketoResponse<ObjectNode> marketoResponse = new MarketoResponse<>();
150
+ marketoResponse.setSuccess(true);
151
+ Date startDate = new Date(1506865856000L);
152
+ Date endDate = new Date(1507297856000L);
153
+ List<Integer> activityTypeIds = new ArrayList<>();
154
+ ObjectNode bulkExtractResult = OBJECT_MAPPER.createObjectNode();
155
+ bulkExtractResult.set("exportId", new TextNode("bulkExtractId"));
156
+ marketoResponse.setResult(Arrays.asList(bulkExtractResult));
157
+ ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
158
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.CREATE_ACTIVITY_EXTRACT.getEndpoint()), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), argumentCaptor.capture(), Mockito.any(MarketoResponseJetty92EntityReader.class));
159
+ String bulkExtractId = marketoRestClient.createActivityExtract(activityTypeIds, startDate, endDate);
160
+ Assert.assertEquals("bulkExtractId", bulkExtractId);
161
+ String postContent = argumentCaptor.getValue();
162
+ ObjectNode marketoBulkExtractRequest = (ObjectNode) OBJECT_MAPPER.readTree(postContent);
163
+ ObjectNode filter = (ObjectNode) marketoBulkExtractRequest.get("filter");
164
+ Assert.assertTrue(filter.has("createdAt"));
165
+ }
166
+
167
+ @Test
168
+ public void startLeadBulkExtract() throws Exception
169
+ {
170
+ String bulkExportId = "bulkExportId";
171
+ Map<String, String> pathParams = new HashMap<>();
172
+ pathParams.put("export_id", bulkExportId);
173
+ MarketoResponse<ObjectNode> marketoResponse = new MarketoResponse<>();
174
+ marketoResponse.setSuccess(true);
175
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.START_LEAD_EXPORT_JOB.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.isNull(String.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
176
+ marketoRestClient.startLeadBulkExtract(bulkExportId);
177
+ Mockito.verify(marketoRestClient, Mockito.times(1)).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.START_LEAD_EXPORT_JOB.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.isNull(String.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
178
+ }
179
+
180
+ @Test
181
+ public void startLeadBulkExtractWithError() throws Exception
182
+ {
183
+ String bulkExportId = "bulkExportId";
184
+ Map<String, String> pathParams = new HashMap<>();
185
+ pathParams.put("export_id", bulkExportId);
186
+ MarketoResponse<ObjectNode> marketoResponse = new MarketoResponse<>();
187
+ marketoResponse.setSuccess(false);
188
+ MarketoError marketoError = new MarketoError();
189
+ marketoError.setCode("ErrorCode");
190
+ marketoError.setMessage("Message");
191
+ marketoResponse.setErrors(Arrays.asList(marketoError));
192
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.START_LEAD_EXPORT_JOB.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.isNull(String.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
193
+ try {
194
+ marketoRestClient.startLeadBulkExtract(bulkExportId);
195
+ }
196
+ catch (DataException ex) {
197
+ Mockito.verify(marketoRestClient, Mockito.times(1)).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.START_LEAD_EXPORT_JOB.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.isNull(String.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
198
+ return;
199
+ }
200
+ Assert.fail();
201
+ }
202
+
203
+ @Test
204
+ public void startActivityBulkExtract() throws Exception
205
+ {
206
+ String bulkExportId = "bulkExportId";
207
+ Map<String, String> pathParams = new HashMap<>();
208
+ pathParams.put("export_id", bulkExportId);
209
+ MarketoResponse<ObjectNode> marketoResponse = new MarketoResponse<>();
210
+ marketoResponse.setSuccess(true);
211
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.START_ACTIVITY_EXPORT_JOB.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.isNull(String.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
212
+ marketoRestClient.startActitvityBulkExtract(bulkExportId);
213
+ Mockito.verify(marketoRestClient, Mockito.times(1)).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.START_ACTIVITY_EXPORT_JOB.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.isNull(String.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
214
+ }
215
+
216
+ @Test
217
+ public void waitLeadExportJobComplete() throws Exception
218
+ {
219
+ String bulkExportId = "bulkExportId";
220
+ Map<String, String> pathParams = new HashMap<>();
221
+ pathParams.put("export_id", bulkExportId);
222
+ MarketoResponse<ObjectNode> marketoResponse = Mockito.mock(MarketoResponse.class);
223
+ Mockito.when(marketoResponse.isSuccess()).thenReturn(true);
224
+ ObjectNode result = Mockito.mock(ObjectNode.class);
225
+ Mockito.when(marketoResponse.getResult()).thenReturn(Arrays.asList(result));
226
+ Mockito.when(result.get("status")).thenReturn(new TextNode("Queued")).thenReturn(new TextNode("Processing")).thenReturn(new TextNode("Completed"));
227
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEAD_EXPORT_STATUS.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
228
+ marketoRestClient.waitLeadExportJobComplete(bulkExportId, 1, 4);
229
+ Mockito.verify(marketoRestClient, Mockito.times(3)).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEAD_EXPORT_STATUS.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
230
+ }
231
+
232
+ @Test
233
+ public void waitLeadExportJobTimeOut() throws Exception
234
+ {
235
+ String bulkExportId = "bulkExportId";
236
+ Map<String, String> pathParams = new HashMap<>();
237
+ pathParams.put("export_id", bulkExportId);
238
+ MarketoResponse<ObjectNode> marketoResponse = Mockito.mock(MarketoResponse.class);
239
+ Mockito.when(marketoResponse.isSuccess()).thenReturn(true);
240
+ ObjectNode result = Mockito.mock(ObjectNode.class);
241
+ Mockito.when(marketoResponse.getResult()).thenReturn(Arrays.asList(result));
242
+ Mockito.when(result.get("status")).thenReturn(new TextNode("Queued")).thenReturn(new TextNode("Processing"));
243
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEAD_EXPORT_STATUS.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
244
+ try {
245
+ marketoRestClient.waitLeadExportJobComplete(bulkExportId, 2, 4);
246
+ }
247
+ catch (DataException e) {
248
+ Assert.assertTrue(e.getMessage().contains("Job timeout exception"));
249
+ Mockito.verify(marketoRestClient, Mockito.times(2)).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEAD_EXPORT_STATUS.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
250
+ return;
251
+ }
252
+ Assert.fail();
253
+ }
254
+
255
+ @Test
256
+ public void waitLeadExportJobFailed() throws Exception
257
+ {
258
+ String bulkExportId = "bulkExportId";
259
+ Map<String, String> pathParams = new HashMap<>();
260
+ pathParams.put("export_id", bulkExportId);
261
+ MarketoResponse<ObjectNode> marketoResponse = Mockito.mock(MarketoResponse.class);
262
+ Mockito.when(marketoResponse.isSuccess()).thenReturn(true);
263
+ ObjectNode result = Mockito.mock(ObjectNode.class);
264
+ Mockito.when(marketoResponse.getResult()).thenReturn(Arrays.asList(result));
265
+ Mockito.when(result.get("status")).thenReturn(new TextNode("Queued")).thenReturn(new TextNode("Failed"));
266
+ Mockito.when(result.get("errorMsg")).thenReturn(new TextNode("ErrorMessage"));
267
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEAD_EXPORT_STATUS.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
268
+ try {
269
+ marketoRestClient.waitLeadExportJobComplete(bulkExportId, 1, 4);
270
+ }
271
+ catch (DataException e) {
272
+ Assert.assertTrue(e.getMessage().contains("Bulk extract job failed"));
273
+ Assert.assertTrue(e.getMessage().contains("ErrorMessage"));
274
+ Mockito.verify(marketoRestClient, Mockito.times(2)).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEAD_EXPORT_STATUS.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
275
+ return;
276
+ }
277
+ Assert.fail();
278
+ }
279
+
280
+ @Test
281
+ public void waitActitvityExportJobComplete() throws Exception
282
+ {
283
+ String exportId = "exportId";
284
+ Map<String, String> pathParamMap = new HashMap<>();
285
+ pathParamMap.put("export_id", exportId);
286
+ MarketoResponse<ObjectNode> marketoResponse = Mockito.mock(MarketoResponse.class);
287
+ Mockito.when(marketoResponse.isSuccess()).thenReturn(true);
288
+ ObjectNode mockObjectNode = Mockito.mock(ObjectNode.class);
289
+ Mockito.when(marketoResponse.getResult()).thenReturn(Arrays.asList(mockObjectNode));
290
+ Mockito.when(mockObjectNode.get("status")).thenReturn(new TextNode("Completed"));
291
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doGet(Mockito.anyString(), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(Jetty92ResponseReader.class));
292
+ marketoRestClient.waitActitvityExportJobComplete(exportId, 1, 3);
293
+ Mockito.verify(marketoRestClient, Mockito.times(1)).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_ACTIVITY_EXPORT_STATUS.getEndpoint(pathParamMap)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(Jetty92ResponseReader.class));
294
+ }
295
+
296
+ @Test
297
+ public void getLeadBulkExtractResult() throws Exception
298
+ {
299
+ String exportId = "exportId";
300
+ Map<String, String> pathParamMap = new HashMap<>();
301
+ pathParamMap.put("export_id", exportId);
302
+ Mockito.doReturn(Mockito.mock(InputStream.class)).when(marketoRestClient).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEAD_EXPORT_RESULT.getEndpoint(pathParamMap)), Mockito.any(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoInputStreamResponseEntityReader.class));
303
+ marketoRestClient.getLeadBulkExtractResult(exportId, null);
304
+ Mockito.verify(marketoRestClient, Mockito.times(1)).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEAD_EXPORT_RESULT.getEndpoint(pathParamMap)), Mockito.any(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoInputStreamResponseEntityReader.class));
305
+ }
306
+
307
+ @Test
308
+ public void getActivitiesBulkExtractResult() throws Exception
309
+ {
310
+ String exportId = "exportId";
311
+ Map<String, String> pathParamMap = new HashMap<>();
312
+ pathParamMap.put("export_id", exportId);
313
+ Mockito.doReturn(Mockito.mock(InputStream.class)).when(marketoRestClient).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_ACTIVITY_EXPORT_RESULT.getEndpoint(pathParamMap)), Mockito.any(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoInputStreamResponseEntityReader.class));
314
+ marketoRestClient.getActivitiesBulkExtractResult(exportId, null);
315
+ Mockito.verify(marketoRestClient, Mockito.times(1)).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_ACTIVITY_EXPORT_RESULT.getEndpoint(pathParamMap)), Mockito.any(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoInputStreamResponseEntityReader.class));
316
+ }
317
+
318
+ @Test
319
+ public void getLists() throws Exception
320
+ {
321
+ mockMarketoPageResponse("/fixtures/lists_response.json", END_POINT + MarketoRESTEndpoint.GET_LISTS.getEndpoint());
322
+ RecordPagingIterable<ObjectNode> lists = marketoRestClient.getLists();
323
+ Iterator<ObjectNode> iterator = lists.iterator();
324
+ ObjectNode list1 = iterator.next();
325
+ ObjectNode list2 = iterator.next();
326
+ Assert.assertFalse(iterator.hasNext());
327
+ Assert.assertEquals("Test list 1", list1.get("name").asText());
328
+ Assert.assertEquals("Test list 2", list2.get("name").asText());
329
+ ArgumentCaptor<Multimap> immutableListMultimapArgumentCaptor = ArgumentCaptor.forClass(Multimap.class);
330
+ ArgumentCaptor<FormContentProvider> formContentProviderArgumentCaptor = ArgumentCaptor.forClass(FormContentProvider.class);
331
+ Mockito.verify(marketoRestClient, Mockito.times(2)).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LISTS.getEndpoint()), Mockito.isNull(Map.class), immutableListMultimapArgumentCaptor.capture(), Mockito.any(MarketoResponseJetty92EntityReader.class), formContentProviderArgumentCaptor.capture());
332
+ List<Multimap> params = immutableListMultimapArgumentCaptor.getAllValues();
333
+ Multimap params1 = params.get(0);
334
+ Assert.assertEquals("GET", params1.get("_method").iterator().next());
335
+ Assert.assertEquals("nextPageToken=GWP55GLCVCZLPE6SS7OCG5IEXQ%3D%3D%3D%3D%3D%3D&batchSize=300", fromContentProviderToString(formContentProviderArgumentCaptor.getValue()));
336
+ }
337
+
338
+ @Test
339
+ public void getPrograms() throws Exception
340
+ {
341
+ ArrayNode listPages = (ArrayNode) OBJECT_MAPPER.readTree(new String(ByteStreams.toByteArray(this.getClass().getResourceAsStream("/fixtures/program_response.json")))).get("responses");
342
+ MarketoResponse<ObjectNode> page1 = OBJECT_MAPPER.readValue(listPages.get(0).toString(), RESPONSE_TYPE);
343
+ MarketoResponse<ObjectNode> page2 = OBJECT_MAPPER.readValue(listPages.get(1).toString(), RESPONSE_TYPE);
344
+ Mockito.doReturn(page1).doReturn(page2).when(marketoRestClient).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_PROGRAMS.getEndpoint()), Mockito.isNull(Map.class), Mockito.any(Multimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
345
+ RecordPagingIterable<ObjectNode> lists = marketoRestClient.getPrograms();
346
+ Iterator<ObjectNode> iterator = lists.iterator();
347
+ ObjectNode program1 = iterator.next();
348
+ ObjectNode program2 = iterator.next();
349
+ ObjectNode program3 = iterator.next();
350
+ Assert.assertFalse(iterator.hasNext());
351
+ Assert.assertEquals("MB_Sep_25_test_program", program1.get("name").asText());
352
+ Assert.assertEquals("TD Output Test Program", program2.get("name").asText());
353
+ Assert.assertEquals("Bill_progream", program3.get("name").asText());
354
+ ArgumentCaptor<ImmutableListMultimap> immutableListMultimapArgumentCaptor = ArgumentCaptor.forClass(ImmutableListMultimap.class);
355
+ Mockito.verify(marketoRestClient, Mockito.times(2)).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_PROGRAMS.getEndpoint()), Mockito.isNull(Map.class), immutableListMultimapArgumentCaptor.capture(), Mockito.any(MarketoResponseJetty92EntityReader.class));
356
+ List<ImmutableListMultimap> params = immutableListMultimapArgumentCaptor.getAllValues();
357
+ ImmutableListMultimap params1 = params.get(0);
358
+ Assert.assertEquals("0", params1.get("offset").get(0));
359
+ Assert.assertEquals("2", params1.get("maxReturn").get(0));
360
+ ImmutableListMultimap params2 = params.get(1);
361
+ Assert.assertEquals("2", params2.get("offset").get(0));
362
+ }
363
+
364
+ private void mockMarketoPageResponse(String fixtureName, String mockEndpoint) throws IOException
365
+ {
366
+ ArrayNode listPages = (ArrayNode) OBJECT_MAPPER.readTree(new String(ByteStreams.toByteArray(this.getClass().getResourceAsStream(fixtureName)))).get("responses");
367
+ MarketoResponse<ObjectNode> page1 = OBJECT_MAPPER.readValue(listPages.get(0).toString(), RESPONSE_TYPE);
368
+ MarketoResponse<ObjectNode> page2 = OBJECT_MAPPER.readValue(listPages.get(1).toString(), RESPONSE_TYPE);
369
+ Mockito.doReturn(page1).doReturn(page2).when(marketoRestClient).doPost(Mockito.eq(mockEndpoint), Mockito.isNull(Map.class), Mockito.any(Multimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class), Mockito.any(FormContentProvider.class));
370
+ }
371
+
372
+ @Test
373
+ public void getLeadsByProgram() throws Exception
374
+ {
375
+ String programId = "programId";
376
+ Map<String, String> pathParamPath = new HashMap<>();
377
+ pathParamPath.put("program_id", programId);
378
+ mockMarketoPageResponse("/fixtures/lead_by_program_response.json", END_POINT + MarketoRESTEndpoint.GET_LEADS_BY_PROGRAM.getEndpoint(pathParamPath));
379
+ RecordPagingIterable<ObjectNode> lists = marketoRestClient.getLeadsByProgram(programId, "firstName,lastName");
380
+ Iterator<ObjectNode> iterator = lists.iterator();
381
+ ObjectNode lead1 = iterator.next();
382
+ ObjectNode lead2 = iterator.next();
383
+ Assert.assertFalse(iterator.hasNext());
384
+ Assert.assertEquals("Tai 1", lead1.get("firstName").asText());
385
+ Assert.assertEquals("Tai", lead2.get("firstName").asText());
386
+ ArgumentCaptor<ImmutableListMultimap> immutableListMultimapArgumentCaptor = ArgumentCaptor.forClass(ImmutableListMultimap.class);
387
+ ArgumentCaptor<FormContentProvider> formContentProviderArgumentCaptor = ArgumentCaptor.forClass(FormContentProvider.class);
388
+ Mockito.verify(marketoRestClient, Mockito.times(2)).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEADS_BY_PROGRAM.getEndpoint(pathParamPath)), Mockito.isNull(Map.class), immutableListMultimapArgumentCaptor.capture(), Mockito.any(MarketoResponseJetty92EntityReader.class), formContentProviderArgumentCaptor.capture());
389
+ String formContent = fromContentProviderToString(formContentProviderArgumentCaptor.getValue());
390
+ List<ImmutableListMultimap> params = immutableListMultimapArgumentCaptor.getAllValues();
391
+ Multimap params1 = params.get(0);
392
+ Assert.assertEquals("GET", params1.get("_method").iterator().next());
393
+ Assert.assertEquals("nextPageToken=z4MgsIiC5C%3D%3D%3D%3D%3D%3D&batchSize=300&fields=firstName%2ClastName", formContent);
394
+ }
395
+
396
+ private String fromContentProviderToString(ContentProvider formContentProvider)
397
+ {
398
+ Iterator<ByteBuffer> byteBufferIterator = formContentProvider.iterator();
399
+ StringBuilder stringBuilder = new StringBuilder();
400
+ while (byteBufferIterator.hasNext()) {
401
+ ByteBuffer next = byteBufferIterator.next();
402
+ stringBuilder.append(new String(next.array()));
403
+ }
404
+ return stringBuilder.toString();
405
+ }
406
+
407
+ @Test
408
+ public void getLeadsByList() throws Exception
409
+ {
410
+ String listId = "listId";
411
+ Map<String, String> pathParamPath = new HashMap<>();
412
+ pathParamPath.put("list_id", listId);
413
+ mockMarketoPageResponse("/fixtures/lead_by_list.json", END_POINT + MarketoRESTEndpoint.GET_LEADS_BY_LIST.getEndpoint(pathParamPath));
414
+ RecordPagingIterable<ObjectNode> lists = marketoRestClient.getLeadsByList(listId, "firstName,lastName");
415
+ Iterator<ObjectNode> iterator = lists.iterator();
416
+ ObjectNode lead1 = iterator.next();
417
+ ObjectNode lead2 = iterator.next();
418
+ Assert.assertFalse(iterator.hasNext());
419
+ Assert.assertEquals("John10093", lead1.get("firstName").asText());
420
+ Assert.assertEquals("John10094", lead2.get("firstName").asText());
421
+ ArgumentCaptor<ImmutableListMultimap> immutableListMultimapArgumentCaptor = ArgumentCaptor.forClass(ImmutableListMultimap.class);
422
+ ArgumentCaptor<FormContentProvider> formContentProviderArgumentCaptor = ArgumentCaptor.forClass(FormContentProvider.class);
423
+ Mockito.verify(marketoRestClient, Mockito.times(2)).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_LEADS_BY_LIST.getEndpoint(pathParamPath)), Mockito.isNull(Map.class), immutableListMultimapArgumentCaptor.capture(), Mockito.any(MarketoResponseJetty92EntityReader.class), formContentProviderArgumentCaptor.capture());
424
+ String formContent = fromContentProviderToString(formContentProviderArgumentCaptor.getValue());
425
+ List<ImmutableListMultimap> params = immutableListMultimapArgumentCaptor.getAllValues();
426
+ Multimap params1 = params.get(0);
427
+ Assert.assertEquals("GET", params1.get("_method").iterator().next());
428
+ Assert.assertEquals("nextPageToken=z4MgsIiC5C%3D%3D%3D%3D%3D%3D&batchSize=300&fields=firstName%2ClastName", formContent);
429
+ }
430
+
431
+ @Test
432
+ public void getCampaign() throws Exception
433
+ {
434
+ mockMarketoPageResponse("/fixtures/campaign_response.json", END_POINT + MarketoRESTEndpoint.GET_CAMPAIGN.getEndpoint());
435
+ RecordPagingIterable<ObjectNode> lists = marketoRestClient.getCampaign();
436
+ Iterator<ObjectNode> iterator = lists.iterator();
437
+ ObjectNode campaign1 = iterator.next();
438
+ ObjectNode campaign2 = iterator.next();
439
+ Assert.assertFalse(iterator.hasNext());
440
+ Assert.assertEquals("Opened Sales Email", campaign1.get("name").asText());
441
+ Assert.assertEquals("Clicks Link in Email", campaign2.get("name").asText());
442
+ ArgumentCaptor<ImmutableListMultimap> immutableListMultimapArgumentCaptor = ArgumentCaptor.forClass(ImmutableListMultimap.class);
443
+ ArgumentCaptor<FormContentProvider> formContentProviderArgumentCaptor = ArgumentCaptor.forClass(FormContentProvider.class);
444
+ Mockito.verify(marketoRestClient, Mockito.times(2)).doPost(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_CAMPAIGN.getEndpoint()), Mockito.isNull(Map.class), immutableListMultimapArgumentCaptor.capture(), Mockito.any(MarketoResponseJetty92EntityReader.class), formContentProviderArgumentCaptor.capture());
445
+ String content = fromContentProviderToString(formContentProviderArgumentCaptor.getValue());
446
+
447
+ List<ImmutableListMultimap> params = immutableListMultimapArgumentCaptor.getAllValues();
448
+ Multimap params1 = params.get(0);
449
+ Assert.assertEquals("GET", params1.get("_method").iterator().next());
450
+ Assert.assertEquals("nextPageToken=z4MgsIiC5C%3D%3D%3D%3D%3D%3D&batchSize=300", content);
451
+ }
452
+
453
+ @Test
454
+ public void testGetProgramsByTagType() throws Exception
455
+ {
456
+ ArrayNode listPages = (ArrayNode) OBJECT_MAPPER.readTree(new String(ByteStreams.toByteArray(this.getClass().getResourceAsStream("/fixtures/program_response.json")))).get("responses");
457
+ MarketoResponse<ObjectNode> page1 = OBJECT_MAPPER.readValue(listPages.get(0).toString(), RESPONSE_TYPE);
458
+ MarketoResponse<ObjectNode> page2 = OBJECT_MAPPER.readValue(listPages.get(1).toString(), RESPONSE_TYPE);
459
+
460
+ final String tagType = "dummy_tag";
461
+ final String tagValue = "dummy_value";
462
+
463
+ Mockito.doReturn(page1).doReturn(page2).when(marketoRestClient).doGet(
464
+ Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_PROGRAMS_BY_TAG.getEndpoint()),
465
+ (Map) ArgumentMatchers.isNull(),
466
+ Mockito.any(Multimap.class),
467
+ Mockito.any(MarketoResponseJetty92EntityReader.class));
468
+ Iterable<ObjectNode> lists = marketoRestClient.getProgramsByTag(tagType, tagValue);
469
+ Iterator<ObjectNode> iterator = lists.iterator();
470
+ ObjectNode program1 = iterator.next();
471
+ ObjectNode program2 = iterator.next();
472
+ ObjectNode program3 = iterator.next();
473
+ Assert.assertFalse(iterator.hasNext());
474
+ Assert.assertEquals("MB_Sep_25_test_program", program1.get("name").asText());
475
+ Assert.assertEquals("TD Output Test Program", program2.get("name").asText());
476
+ Assert.assertEquals("Bill_progream", program3.get("name").asText());
477
+
478
+ ArgumentCaptor<ImmutableListMultimap> immutableListMultimapArgumentCaptor = ArgumentCaptor.forClass(ImmutableListMultimap.class);
479
+ Mockito.verify(marketoRestClient, Mockito.times(2)).doGet(
480
+ Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_PROGRAMS_BY_TAG.getEndpoint()),
481
+ (Map) ArgumentMatchers.isNull(),
482
+ immutableListMultimapArgumentCaptor.capture(),
483
+ Mockito.any(MarketoResponseJetty92EntityReader.class));
484
+ List<ImmutableListMultimap> params = immutableListMultimapArgumentCaptor.getAllValues();
485
+
486
+ ImmutableListMultimap params1 = params.get(0);
487
+ Assert.assertEquals("0", params1.get("offset").get(0));
488
+ Assert.assertEquals("2", params1.get("maxReturn").get(0));
489
+ Assert.assertEquals("dummy_tag", params1.get("tagType").get(0));
490
+ Assert.assertEquals("dummy_value", params1.get("tagValue").get(0));
491
+
492
+ ImmutableListMultimap params2 = params.get(1);
493
+ Assert.assertEquals("2", params2.get("offset").get(0));
494
+ Assert.assertEquals("dummy_tag", params2.get("tagType").get(0));
495
+ Assert.assertEquals("dummy_value", params2.get("tagValue").get(0));
496
+ }
497
+
498
+ @Test
499
+ public void TestProgramsByDateRange() throws Exception
500
+ {
501
+ ArrayNode listPages = (ArrayNode) OBJECT_MAPPER.readTree(new String(ByteStreams.toByteArray(this.getClass().getResourceAsStream("/fixtures/program_response.json")))).get("responses");
502
+ MarketoResponse<ObjectNode> page1 = OBJECT_MAPPER.readValue(listPages.get(0).toString(), RESPONSE_TYPE);
503
+ MarketoResponse<ObjectNode> page2 = OBJECT_MAPPER.readValue(listPages.get(1).toString(), RESPONSE_TYPE);
504
+
505
+ Mockito.doReturn(page1).doReturn(page2).when(marketoRestClient).doGet(
506
+ Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_PROGRAMS.getEndpoint()),
507
+ (Map) ArgumentMatchers.isNull(),
508
+ Mockito.any(Multimap.class),
509
+ Mockito.any(MarketoResponseJetty92EntityReader.class));
510
+ DateTime earliestUpdatedAt = DateTime.now().minusDays(10);
511
+ DateTime latestUpdatedAt = earliestUpdatedAt.plusDays(5);
512
+ String filterType = "filter1";
513
+ List<String> filterValues = Arrays.asList("value1", "value2");
514
+
515
+ Iterable<ObjectNode> lists = marketoRestClient.getProgramsByDateRange(earliestUpdatedAt.toDate(), latestUpdatedAt.toDate(), filterType, filterValues);
516
+ Iterator<ObjectNode> iterator = lists.iterator();
517
+ ObjectNode program1 = iterator.next();
518
+ ObjectNode program2 = iterator.next();
519
+ ObjectNode program3 = iterator.next();
520
+ Assert.assertFalse(iterator.hasNext());
521
+ Assert.assertEquals("MB_Sep_25_test_program", program1.get("name").asText());
522
+ Assert.assertEquals("TD Output Test Program", program2.get("name").asText());
523
+ Assert.assertEquals("Bill_progream", program3.get("name").asText());
524
+
525
+ ArgumentCaptor<ImmutableListMultimap> immutableListMultimapArgumentCaptor = ArgumentCaptor.forClass(ImmutableListMultimap.class);
526
+ Mockito.verify(marketoRestClient, Mockito.times(2)).doGet(
527
+ Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_PROGRAMS.getEndpoint()),
528
+ (Map) ArgumentMatchers.isNull(),
529
+ immutableListMultimapArgumentCaptor.capture(),
530
+ Mockito.any(MarketoResponseJetty92EntityReader.class));
531
+ List<ImmutableListMultimap> params = immutableListMultimapArgumentCaptor.getAllValues();
532
+ DateTimeFormatter fmt = DateTimeFormat.forPattern(MarketoUtils.MARKETO_DATE_SIMPLE_DATE_FORMAT);
533
+
534
+ ImmutableListMultimap params1 = params.get(0);
535
+ Assert.assertEquals("0", params1.get("offset").get(0));
536
+ Assert.assertEquals("2", params1.get("maxReturn").get(0));
537
+ Assert.assertEquals(earliestUpdatedAt.toString(fmt), params1.get("earliestUpdatedAt").get(0));
538
+ Assert.assertEquals(latestUpdatedAt.toString(fmt), params1.get("latestUpdatedAt").get(0));
539
+ Assert.assertEquals("filter1", params1.get("filterType").get(0));
540
+ Assert.assertEquals(String.join(",", filterValues), params1.get("filterValues").get(0));
541
+
542
+ ImmutableListMultimap params2 = params.get(1);
543
+ Assert.assertEquals("2", params2.get("offset").get(0));
544
+ Assert.assertEquals(earliestUpdatedAt.toString(fmt), params2.get("earliestUpdatedAt").get(0));
545
+ Assert.assertEquals(latestUpdatedAt.toString(fmt), params2.get("latestUpdatedAt").get(0));
546
+ Assert.assertEquals("filter1", params2.get("filterType").get(0));
547
+ Assert.assertEquals(String.join(",", filterValues), params2.get("filterValues").get(0));
548
+ }
549
+
550
+ @Test
551
+ public void describeCustomObject() throws Exception
552
+ {
553
+ String customObjectSchema = new String(ByteStreams.toByteArray(this.getClass().getResourceAsStream("/fixtures/custom_object_describe.json")));
554
+ MarketoResponse<ObjectNode> marketoResponse = OBJECT_MAPPER.readValue(customObjectSchema, RESPONSE_TYPE);
555
+ String apiName = "custom_object";
556
+ Map<String, String> pathParams = new HashMap<>();
557
+ pathParams.put("api_name", apiName);
558
+ Mockito.doReturn(marketoResponse).when(marketoRestClient).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_CUSTOM_OBJECT_DESCRIBE.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.isNull(ImmutableListMultimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
559
+ List<MarketoField> marketoFields = marketoRestClient.describeCustomObject(apiName);
560
+ Assert.assertEquals(16, marketoFields.size());
561
+ JavaType marketoFieldType = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, MarketoField.class);
562
+ List<MarketoField> expectedFields = OBJECT_MAPPER.readValue(new String(ByteStreams.toByteArray(this.getClass().getResourceAsStream("/fixtures/custom_object_expected.json"))), marketoFieldType);
563
+ Assert.assertArrayEquals(expectedFields.toArray(), marketoFields.toArray());
564
+ }
565
+
566
+ @Test
567
+ public void getCustomObject() throws Exception
568
+ {
569
+ String apiName = "custom_object";
570
+ Map<String, String> pathParams = new HashMap<>();
571
+ pathParams.put("api_name", apiName);
572
+
573
+ ArrayNode listPages = (ArrayNode) OBJECT_MAPPER.readTree(new String(ByteStreams.toByteArray(this.getClass().getResourceAsStream("/fixtures/custom_object_response.json")))).get("responses");
574
+ MarketoResponse<ObjectNode> page1 = OBJECT_MAPPER.readValue(listPages.get(0).toString(), RESPONSE_TYPE);
575
+ Mockito.doReturn(page1).when(marketoRestClient).doGet(Mockito.eq(END_POINT + MarketoRESTEndpoint.GET_CUSTOM_OBJECT.getEndpoint(pathParams)), Mockito.isNull(Map.class), Mockito.any(ImmutableListMultimap.class), Mockito.any(MarketoResponseJetty92EntityReader.class));
576
+ RecordPagingIterable<ObjectNode> pages = (RecordPagingIterable<ObjectNode>) marketoRestClient.getCustomObject(apiName, "id", null, 1, 2);
577
+ Iterator<ObjectNode> iterator = pages.iterator();
578
+ ObjectNode customObject1 = iterator.next();
579
+ ObjectNode customObject2 = iterator.next();
580
+ Assert.assertFalse(iterator.hasNext());
581
+ Assert.assertEquals("1", customObject1.get("id").asText());
582
+ Assert.assertEquals("2", customObject2.get("id").asText());
583
+ }
584
+ }