embulk-input-zendesk-all 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +5 -0
  4. data/CHANGELOG.md +126 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +91 -0
  7. data/build.gradle +123 -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 +5 -0
  12. data/gradlew +172 -0
  13. data/gradlew.bat +84 -0
  14. data/lib/embulk/guess/zendesk.rb +21 -0
  15. data/lib/embulk/input/zendesk.rb +3 -0
  16. data/src/main/java/org/embulk/input/zendesk/RecordImporter.java +134 -0
  17. data/src/main/java/org/embulk/input/zendesk/ZendeskInputPlugin.java +513 -0
  18. data/src/main/java/org/embulk/input/zendesk/clients/ZendeskRestClient.java +291 -0
  19. data/src/main/java/org/embulk/input/zendesk/models/AuthenticationMethod.java +23 -0
  20. data/src/main/java/org/embulk/input/zendesk/models/Target.java +47 -0
  21. data/src/main/java/org/embulk/input/zendesk/models/ZendeskException.java +25 -0
  22. data/src/main/java/org/embulk/input/zendesk/services/ZendeskCustomObjectService.java +110 -0
  23. data/src/main/java/org/embulk/input/zendesk/services/ZendeskNPSService.java +30 -0
  24. data/src/main/java/org/embulk/input/zendesk/services/ZendeskNormalServices.java +347 -0
  25. data/src/main/java/org/embulk/input/zendesk/services/ZendeskService.java +14 -0
  26. data/src/main/java/org/embulk/input/zendesk/services/ZendeskSupportAPIService.java +63 -0
  27. data/src/main/java/org/embulk/input/zendesk/services/ZendeskUserEventService.java +158 -0
  28. data/src/main/java/org/embulk/input/zendesk/stream/PagingSpliterator.java +40 -0
  29. data/src/main/java/org/embulk/input/zendesk/stream/paginator/sunshine/CustomObjectSpliterator.java +42 -0
  30. data/src/main/java/org/embulk/input/zendesk/stream/paginator/sunshine/SunshineSpliterator.java +66 -0
  31. data/src/main/java/org/embulk/input/zendesk/stream/paginator/sunshine/UserEventSpliterator.java +35 -0
  32. data/src/main/java/org/embulk/input/zendesk/stream/paginator/support/OrganizationSpliterator.java +13 -0
  33. data/src/main/java/org/embulk/input/zendesk/stream/paginator/support/SupportSpliterator.java +44 -0
  34. data/src/main/java/org/embulk/input/zendesk/stream/paginator/support/UserSpliterator.java +13 -0
  35. data/src/main/java/org/embulk/input/zendesk/utils/ZendeskConstants.java +72 -0
  36. data/src/main/java/org/embulk/input/zendesk/utils/ZendeskDateUtils.java +68 -0
  37. data/src/main/java/org/embulk/input/zendesk/utils/ZendeskUtils.java +92 -0
  38. data/src/test/java/org/embulk/input/zendesk/TestRecordImporter.java +114 -0
  39. data/src/test/java/org/embulk/input/zendesk/TestZendeskInputPlugin.java +402 -0
  40. data/src/test/java/org/embulk/input/zendesk/clients/TestZendeskRestClient.java +337 -0
  41. data/src/test/java/org/embulk/input/zendesk/services/TestZendeskCustomObjectService.java +161 -0
  42. data/src/test/java/org/embulk/input/zendesk/services/TestZendeskNPSService.java +56 -0
  43. data/src/test/java/org/embulk/input/zendesk/services/TestZendeskNormalService.java +261 -0
  44. data/src/test/java/org/embulk/input/zendesk/services/TestZendeskSupportAPIService.java +130 -0
  45. data/src/test/java/org/embulk/input/zendesk/services/TestZendeskUserEventService.java +158 -0
  46. data/src/test/java/org/embulk/input/zendesk/utils/TestZendeskDateUtils.java +87 -0
  47. data/src/test/java/org/embulk/input/zendesk/utils/TestZendeskUtil.java +22 -0
  48. data/src/test/java/org/embulk/input/zendesk/utils/ZendeskPluginTestRuntime.java +133 -0
  49. data/src/test/java/org/embulk/input/zendesk/utils/ZendeskTestHelper.java +92 -0
  50. data/src/test/resources/config/base.yml +14 -0
  51. data/src/test/resources/config/base_validator.yml +48 -0
  52. data/src/test/resources/config/incremental.yml +54 -0
  53. data/src/test/resources/config/non-incremental.yml +39 -0
  54. data/src/test/resources/config/nps.yml +31 -0
  55. data/src/test/resources/config/object_records.yml +24 -0
  56. data/src/test/resources/config/relationship_records.yml +23 -0
  57. data/src/test/resources/config/user_events.yml +29 -0
  58. data/src/test/resources/config/util.yml +18 -0
  59. data/src/test/resources/data/client.json +293 -0
  60. data/src/test/resources/data/duplicate_user.json +0 -0
  61. data/src/test/resources/data/empty_result.json +7 -0
  62. data/src/test/resources/data/error_data.json +187 -0
  63. data/src/test/resources/data/expected/ticket_column.json +148 -0
  64. data/src/test/resources/data/expected/ticket_column_with_related_objects.json +152 -0
  65. data/src/test/resources/data/expected/ticket_fields_column.json +92 -0
  66. data/src/test/resources/data/expected/ticket_metrics_column.json +98 -0
  67. data/src/test/resources/data/expected/user_events_column.json +40 -0
  68. data/src/test/resources/data/object_records.json +30 -0
  69. data/src/test/resources/data/organization.json +39 -0
  70. data/src/test/resources/data/relationship_records.json +57 -0
  71. data/src/test/resources/data/scores.json +21 -0
  72. data/src/test/resources/data/scores_share_same_time_with_next_page.json +35 -0
  73. data/src/test/resources/data/scores_share_same_time_without_next_page.json +35 -0
  74. data/src/test/resources/data/simple_organization.json +23 -0
  75. data/src/test/resources/data/simple_user.json +50 -0
  76. data/src/test/resources/data/simple_user_event.json +19 -0
  77. data/src/test/resources/data/ticket_events_share_same_time_with_next_page.json +279 -0
  78. data/src/test/resources/data/ticket_events_share_same_time_without_next_page.json +279 -0
  79. data/src/test/resources/data/ticket_events_updated_by_system_records.json +279 -0
  80. data/src/test/resources/data/ticket_fields.json +225 -0
  81. data/src/test/resources/data/ticket_metrics.json +397 -0
  82. data/src/test/resources/data/ticket_share_same_time_with_next_page.json +232 -0
  83. data/src/test/resources/data/ticket_share_same_time_without_next_page.json +232 -0
  84. data/src/test/resources/data/ticket_with_related_objects.json +67 -0
  85. data/src/test/resources/data/ticket_with_updated_by_system_records.json +187 -0
  86. data/src/test/resources/data/tickets.json +232 -0
  87. data/src/test/resources/data/tickets_continue.json +52 -0
  88. data/src/test/resources/data/user_event.json +19 -0
  89. data/src/test/resources/data/user_event_contain_latter_create_at.json +19 -0
  90. data/src/test/resources/data/user_event_multiple.json +33 -0
  91. data/src/test/resources/data/util.json +19 -0
  92. data/src/test/resources/data/util_page.json +227 -0
  93. metadata +168 -0
@@ -0,0 +1,56 @@
1
+ package org.embulk.input.zendesk.services;
2
+
3
+ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4
+ import org.embulk.EmbulkTestRuntime;
5
+ import org.embulk.input.zendesk.ZendeskInputPlugin;
6
+ import org.embulk.input.zendesk.clients.ZendeskRestClient;
7
+ import org.embulk.input.zendesk.utils.ZendeskTestHelper;
8
+ import org.junit.Before;
9
+ import org.junit.Rule;
10
+ import org.junit.Test;
11
+
12
+ import static org.junit.Assert.assertEquals;
13
+ import static org.mockito.Mockito.mock;
14
+ import static org.mockito.Mockito.spy;
15
+
16
+ import static org.mockito.Mockito.when;
17
+
18
+ public class TestZendeskNPSService
19
+ {
20
+ @Rule
21
+ @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
22
+ public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
23
+
24
+ private ZendeskRestClient zendeskRestClient;
25
+
26
+ private ZendeskNPSService zendeskNPSService;
27
+
28
+ @Before
29
+ public void prepare()
30
+ {
31
+ zendeskRestClient = mock(ZendeskRestClient.class);
32
+ }
33
+
34
+ @Test
35
+ public void testBuildURL()
36
+ {
37
+ setup();
38
+ String expectedString = "https://abc.zendesk.com/api/v2/nps/incremental/responses.json?start_time=10000";
39
+ // only use start_time so page any value
40
+ String actualString = zendeskNPSService.buildURI(0, 10000);
41
+ assertEquals(expectedString, actualString);
42
+ }
43
+
44
+ private void setupZendeskNPSService(ZendeskInputPlugin.PluginTask task)
45
+ {
46
+ zendeskNPSService = spy(new ZendeskNPSService(task));
47
+ when(zendeskNPSService.getZendeskRestClient()).thenReturn(zendeskRestClient);
48
+ }
49
+
50
+ private void setup()
51
+ {
52
+ ZendeskInputPlugin.PluginTask task = ZendeskTestHelper.getConfigSource("nps.yml")
53
+ .loadConfig(ZendeskInputPlugin.PluginTask.class);
54
+ setupZendeskNPSService(task);
55
+ }
56
+ }
@@ -0,0 +1,261 @@
1
+ package org.embulk.input.zendesk.services;
2
+
3
+ import com.fasterxml.jackson.databind.JsonNode;
4
+ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
5
+ import org.embulk.EmbulkTestRuntime;
6
+ import org.embulk.config.ConfigSource;
7
+ import org.embulk.config.TaskReport;
8
+ import org.embulk.input.zendesk.RecordImporter;
9
+ import org.embulk.input.zendesk.ZendeskInputPlugin;
10
+ import org.embulk.input.zendesk.clients.ZendeskRestClient;
11
+ import org.embulk.input.zendesk.models.Target;
12
+ import org.embulk.input.zendesk.utils.ZendeskConstants;
13
+ import org.embulk.input.zendesk.utils.ZendeskTestHelper;
14
+ import org.junit.Assert;
15
+ import org.junit.Before;
16
+ import org.junit.Rule;
17
+ import org.junit.Test;
18
+ import org.mockito.ArgumentCaptor;
19
+
20
+ import java.time.Instant;
21
+
22
+ import static org.junit.Assert.assertEquals;
23
+ import static org.mockito.ArgumentMatchers.any;
24
+ import static org.mockito.ArgumentMatchers.anyBoolean;
25
+ import static org.mockito.Mockito.mock;
26
+ import static org.mockito.Mockito.spy;
27
+ import static org.mockito.Mockito.times;
28
+ import static org.mockito.Mockito.verify;
29
+ import static org.mockito.Mockito.when;
30
+
31
+ public class TestZendeskNormalService
32
+ {
33
+ @Rule
34
+ @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
35
+ public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
36
+
37
+ private ZendeskRestClient zendeskRestClient;
38
+
39
+ private ZendeskSupportAPIService zendeskSupportAPIService;
40
+
41
+ private RecordImporter recordImporter;
42
+
43
+ @Before
44
+ public void prepare()
45
+ {
46
+ zendeskRestClient = mock(ZendeskRestClient.class);
47
+ recordImporter = mock(RecordImporter.class);
48
+ }
49
+
50
+ @Test
51
+ public void testAddRecordToImporterWithIncremental()
52
+ {
53
+ setupSupportAPIService("incremental.yml");
54
+ loadData("data/tickets.json");
55
+
56
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
57
+ verify(recordImporter, times(4)).addRecord(any());
58
+ Assert.assertFalse(taskReport.isEmpty());
59
+ Assert.assertEquals(1550647054, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
60
+ }
61
+
62
+ @Test
63
+ public void testAddRecordToImporterWithIncrementalAndWithoutDedup()
64
+ {
65
+ ConfigSource src = ZendeskTestHelper.getConfigSource("incremental.yml");
66
+ src.set("dedup", false);
67
+ ZendeskInputPlugin.PluginTask task = src.loadConfig(ZendeskInputPlugin.PluginTask.class);
68
+ setupZendeskSupportAPIService(task);
69
+ loadData("data/tickets.json");
70
+
71
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
72
+ verify(recordImporter, times(5)).addRecord(any());
73
+ Assert.assertFalse(taskReport.isEmpty());
74
+ Assert.assertEquals(1550647054, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
75
+ }
76
+
77
+ @Test
78
+ public void testAddRecordToImporterIncrementalContainUpdatedBySystemRecords()
79
+ {
80
+ setupSupportAPIService("incremental.yml");
81
+ loadData("data/ticket_with_updated_by_system_records.json");
82
+
83
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
84
+ verify(recordImporter, times(3)).addRecord(any());
85
+ Assert.assertFalse(taskReport.isEmpty());
86
+ Assert.assertEquals(1550647054, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
87
+ }
88
+
89
+ @Test
90
+ public void testAddRecordToImporterIncrementalUpdateStartTimeWhenEmptyResult()
91
+ {
92
+ ConfigSource src = ZendeskTestHelper.getConfigSource("incremental.yml");
93
+ src.set("target", Target.TICKETS.toString());
94
+
95
+ src.set("start_time", "2219-02-20T06:52:00Z");
96
+ ZendeskInputPlugin.PluginTask task = src.loadConfig(ZendeskInputPlugin.PluginTask.class);
97
+ setupZendeskSupportAPIService(task);
98
+ loadData("data/empty_result.json");
99
+
100
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
101
+ Assert.assertFalse(taskReport.isEmpty());
102
+ Assert.assertTrue(Instant.now().getEpochSecond() <= taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong() + 50);
103
+ }
104
+
105
+ @Test
106
+ public void testAddRecordToImporterNonIncremental()
107
+ {
108
+ setupSupportAPIService("non-incremental.yml");
109
+ loadData("data/ticket_fields.json");
110
+
111
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
112
+ verify(recordImporter, times(7)).addRecord(any());
113
+ Assert.assertTrue(taskReport.isEmpty());
114
+ }
115
+
116
+ @Test
117
+ public void testAddRecordToImporterIncrementalForSupportAndAllRecordsShareTheSameTime()
118
+ {
119
+ setupSupportAPIService("incremental.yml");
120
+ loadData("data/ticket_share_same_time_without_next_page.json");
121
+
122
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
123
+ verify(recordImporter, times(4)).addRecord(any());
124
+ // api_end_time of ticket_share_same_time_without_next_page.json + 1
125
+ Assert.assertEquals(1551419520, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
126
+ }
127
+
128
+ @Test
129
+ public void testTicketEventsAddRecordToImporterIncrementalWithNextPageAndAllRecordsShareTheSameTime()
130
+ {
131
+ // api_end_time of ticket_events_share_same_time_with_next_page.json
132
+ String expectedURL = "https://abc.zendesk.com/api/v2/incremental/ticket_events.json?start_time=1550645443";
133
+ setupSupportAPIService("incremental.yml");
134
+ ZendeskInputPlugin.PluginTask task = ZendeskTestHelper.getConfigSource("incremental.yml")
135
+ .set("target", "ticket_events")
136
+ .loadConfig(ZendeskInputPlugin.PluginTask.class);
137
+ setupZendeskSupportAPIService(task);
138
+
139
+ JsonNode dataJson = ZendeskTestHelper.getJsonFromFile("data/ticket_events_share_same_time_with_next_page.json");
140
+ JsonNode dataJsonNext = ZendeskTestHelper.getJsonFromFile("data/ticket_events_updated_by_system_records.json");
141
+ when(zendeskRestClient.doGet(any(), any(), anyBoolean()))
142
+ .thenReturn(dataJson.toString())
143
+ .thenReturn(dataJsonNext.toString());
144
+
145
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
146
+ final ArgumentCaptor<String> url = ArgumentCaptor.forClass(String.class);
147
+ verify(zendeskRestClient, times(2)).doGet(url.capture(), any(), anyBoolean());
148
+ assertEquals(expectedURL, url.getValue());
149
+
150
+ verify(recordImporter, times(4)).addRecord(any());
151
+ // api_end_time of ticket_events_updated_by_system_records.json + 1
152
+ Assert.assertEquals(1550645523, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
153
+ }
154
+
155
+ @Test
156
+ public void testTicketEventsAddRecordToImporterIncrementalAndAllRecordsShareTheSameTime()
157
+ {
158
+ setupSupportAPIService("incremental.yml");
159
+ ZendeskInputPlugin.PluginTask task = ZendeskTestHelper.getConfigSource("incremental.yml")
160
+ .set("target", "ticket_events")
161
+ .loadConfig(ZendeskInputPlugin.PluginTask.class);
162
+ setupZendeskSupportAPIService(task);
163
+ loadData("data/ticket_events_share_same_time_without_next_page.json");
164
+
165
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
166
+ verify(recordImporter, times(4)).addRecord(any());
167
+ // api_end_time of ticket_events_share_same_time_without_next_page.json + 1
168
+ Assert.assertEquals(1550645444, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
169
+ }
170
+
171
+ @Test
172
+ public void executeIncrementalContainEndTime()
173
+ {
174
+ ConfigSource src = ZendeskTestHelper.getConfigSource("incremental.yml");
175
+ // same updated_at time of last record
176
+ src.set("end_time", "2019-02-20T07:17:32Z");
177
+ ZendeskInputPlugin.PluginTask task = src.loadConfig(ZendeskInputPlugin.PluginTask.class);
178
+ setupZendeskSupportAPIService(task);
179
+ loadData("data/tickets.json");
180
+
181
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
182
+ verify(recordImporter, times(3)).addRecord(any());
183
+ Assert.assertFalse(taskReport.isEmpty());
184
+ // start_time = end_time + 1
185
+ Assert.assertEquals(1550647053, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
186
+ }
187
+
188
+ @Test
189
+ public void executeIncrementalContainEndTimeFilterOutLastRecord()
190
+ {
191
+ ConfigSource src = ZendeskTestHelper.getConfigSource("incremental.yml");
192
+ // earlier than updated_at time of last record
193
+ src.set("end_time", "2019-02-20T07:17:32Z");
194
+ ZendeskInputPlugin.PluginTask task = src.loadConfig(ZendeskInputPlugin.PluginTask.class);
195
+ setupZendeskSupportAPIService(task);
196
+ loadData("data/tickets.json");
197
+
198
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
199
+ verify(recordImporter, times(3)).addRecord(any());
200
+ Assert.assertFalse(taskReport.isEmpty());
201
+ //
202
+ Assert.assertEquals(1550647053, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
203
+ }
204
+
205
+ @Test
206
+ public void executeIncrementalContainEndTimeFilterOutLastRecordTicketEvents()
207
+ {
208
+ ConfigSource src = ZendeskTestHelper.getConfigSource("incremental.yml");
209
+ src.set("target", Target.TICKET_EVENTS.toString());
210
+ // earlier than updated_at time of last record
211
+ // 1550645520
212
+ src.set("end_time", "2019-02-20T06:52:00Z");
213
+ ZendeskInputPlugin.PluginTask task = src.loadConfig(ZendeskInputPlugin.PluginTask.class);
214
+ setupZendeskSupportAPIService(task);
215
+ loadData("data/ticket_events_updated_by_system_records.json");
216
+
217
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
218
+ verify(recordImporter, times(3)).addRecord(any());
219
+ Assert.assertFalse(taskReport.isEmpty());
220
+ // end_time + 1
221
+ Assert.assertEquals(1550645521, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
222
+ }
223
+
224
+ @Test
225
+ public void executeIncrementalContainEndTimeFilterOutLastRecordNPSScore()
226
+ {
227
+ ConfigSource src = ZendeskTestHelper.getConfigSource("nps.yml");
228
+ src.set("target", Target.SCORES.toString());
229
+ // earlier than updated_at time of last record
230
+ // 1550645520
231
+ src.set("end_time", "2019-02-20T06:52:00Z");
232
+ ZendeskInputPlugin.PluginTask task = src.loadConfig(ZendeskInputPlugin.PluginTask.class);
233
+ setupZendeskSupportAPIService(task);
234
+ loadData("data/scores.json");
235
+
236
+ TaskReport taskReport = zendeskSupportAPIService.addRecordToImporter(0, recordImporter);
237
+ verify(recordImporter, times(1)).addRecord(any());
238
+ Assert.assertFalse(taskReport.isEmpty());
239
+ // end_time + 1
240
+ Assert.assertEquals(1550645521, taskReport.get(JsonNode.class, ZendeskConstants.Field.START_TIME).asLong());
241
+ }
242
+
243
+ private void setupSupportAPIService(String file)
244
+ {
245
+ ZendeskInputPlugin.PluginTask task = ZendeskTestHelper.getConfigSource(file)
246
+ .loadConfig(ZendeskInputPlugin.PluginTask.class);
247
+ setupZendeskSupportAPIService(task);
248
+ }
249
+
250
+ private void loadData(String fileName)
251
+ {
252
+ JsonNode dataJson = ZendeskTestHelper.getJsonFromFile(fileName);
253
+ when(zendeskRestClient.doGet(any(), any(), anyBoolean())).thenReturn(dataJson.toString());
254
+ }
255
+
256
+ private void setupZendeskSupportAPIService(ZendeskInputPlugin.PluginTask task)
257
+ {
258
+ zendeskSupportAPIService = spy(new ZendeskSupportAPIService(task));
259
+ when(zendeskSupportAPIService.getZendeskRestClient()).thenReturn(zendeskRestClient);
260
+ }
261
+ }
@@ -0,0 +1,130 @@
1
+ package org.embulk.input.zendesk.services;
2
+
3
+ import com.fasterxml.jackson.databind.JsonNode;
4
+ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
5
+ import org.embulk.EmbulkTestRuntime;
6
+ import org.embulk.config.ConfigSource;
7
+ import org.embulk.input.zendesk.ZendeskInputPlugin;
8
+ import org.embulk.input.zendesk.clients.ZendeskRestClient;
9
+ import org.embulk.input.zendesk.utils.ZendeskTestHelper;
10
+ import org.junit.Before;
11
+ import org.junit.Rule;
12
+ import org.junit.Test;
13
+
14
+ import static org.junit.Assert.assertEquals;
15
+ import static org.mockito.ArgumentMatchers.any;
16
+ import static org.mockito.ArgumentMatchers.anyBoolean;
17
+ import static org.mockito.Mockito.mock;
18
+ import static org.mockito.Mockito.spy;
19
+ import static org.mockito.Mockito.when;
20
+
21
+ import java.util.Collections;
22
+
23
+ public class TestZendeskSupportAPIService
24
+ {
25
+ @Rule
26
+ @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
27
+ public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
28
+
29
+ private ZendeskRestClient zendeskRestClient;
30
+
31
+ private ZendeskSupportAPIService zendeskSupportAPIService;
32
+
33
+ @Before
34
+ public void prepare()
35
+ {
36
+ zendeskRestClient = mock(ZendeskRestClient.class);
37
+ }
38
+
39
+ @Test
40
+ public void testBuildPathWithIncremental()
41
+ {
42
+ String expectURL = "https://abc.zendesk.com/api/v2/incremental/tickets.json?start_time=0";
43
+ setup("incremental.yml");
44
+ loadData("data/tickets.json");
45
+ String url = zendeskSupportAPIService.buildURI(0, 0);
46
+ assertEquals(expectURL, url);
47
+ }
48
+
49
+ @Test
50
+ public void testBuildPathWithIncrementalWithTicketMetrics()
51
+ {
52
+ String expectURL = "https://abc.zendesk.com/api/v2/incremental/tickets.json?start_time=0&include=metric_sets";
53
+ loadData("data/ticket_metrics.json");
54
+
55
+ ConfigSource src = ZendeskTestHelper.getConfigSource("incremental.yml");
56
+ src.set("target", "ticket_metrics");
57
+ ZendeskInputPlugin.PluginTask task = src.loadConfig(ZendeskInputPlugin.PluginTask.class);
58
+ setupZendeskSupportAPIService(task);
59
+
60
+ String url = zendeskSupportAPIService.buildURI(0, 0);
61
+ assertEquals(expectURL, url);
62
+ }
63
+
64
+ @Test
65
+ public void testBuildPathWithIncrementalIncludeRelatedObject()
66
+ {
67
+ String expectURL = "https://abc.zendesk.com/api/v2/incremental/tickets.json?start_time=0";
68
+ loadData("data/tickets.json");
69
+
70
+ ConfigSource src = ZendeskTestHelper.getConfigSource("incremental.yml");
71
+ src.set("includes", Collections.singletonList("organizations"));
72
+ ZendeskInputPlugin.PluginTask task = src.loadConfig(ZendeskInputPlugin.PluginTask.class);
73
+ setupZendeskSupportAPIService(task);
74
+
75
+ String url = zendeskSupportAPIService.buildURI(0, 0);
76
+ assertEquals(expectURL, url);
77
+ }
78
+
79
+ @Test
80
+ public void testBuildPathWithIncrementalTimeChange()
81
+ {
82
+ String expectURL = "https://abc.zendesk.com/api/v2/incremental/tickets.json?start_time=100";
83
+ loadData("data/tickets.json");
84
+
85
+ ConfigSource src = ZendeskTestHelper.getConfigSource("incremental.yml");
86
+ ZendeskInputPlugin.PluginTask task = src.loadConfig(ZendeskInputPlugin.PluginTask.class);
87
+ setupZendeskSupportAPIService(task);
88
+ String url = zendeskSupportAPIService.buildURI(0, 100);
89
+ assertEquals(expectURL, url);
90
+ }
91
+
92
+ @Test
93
+ public void testBuildPathWithNonIncremental()
94
+ {
95
+ String expectURL = "https://abc.zendesk.com/api/v2/ticket_fields.json?sort_by=id&per_page=100&page=0";
96
+ setup("non-incremental.yml");
97
+ loadData("data/ticket_fields.json");
98
+ String url = zendeskSupportAPIService.buildURI(0, 0);
99
+ assertEquals(expectURL, url);
100
+ }
101
+
102
+ @Test
103
+ public void testBuildPathWithNonIncrementalChangePageNumber()
104
+ {
105
+ String expectURL = "https://abc.zendesk.com/api/v2/ticket_fields.json?sort_by=id&per_page=100&page=2";
106
+ setup("non-incremental.yml");
107
+ loadData("data/ticket_fields.json");
108
+ String url = zendeskSupportAPIService.buildURI(2, 0);
109
+ assertEquals(expectURL, url);
110
+ }
111
+
112
+ private void loadData(String fileName)
113
+ {
114
+ JsonNode dataJson = ZendeskTestHelper.getJsonFromFile(fileName);
115
+ when(zendeskRestClient.doGet(any(), any(), anyBoolean())).thenReturn(dataJson.toString());
116
+ }
117
+
118
+ private void setupZendeskSupportAPIService(ZendeskInputPlugin.PluginTask task)
119
+ {
120
+ zendeskSupportAPIService = spy(new ZendeskSupportAPIService(task));
121
+ when(zendeskSupportAPIService.getZendeskRestClient()).thenReturn(zendeskRestClient);
122
+ }
123
+
124
+ private void setup(String file)
125
+ {
126
+ ZendeskInputPlugin.PluginTask task = ZendeskTestHelper.getConfigSource(file)
127
+ .loadConfig(ZendeskInputPlugin.PluginTask.class);
128
+ setupZendeskSupportAPIService(task);
129
+ }
130
+ }
@@ -0,0 +1,158 @@
1
+ package org.embulk.input.zendesk.services;
2
+
3
+ import com.fasterxml.jackson.databind.JsonNode;
4
+ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
5
+ import org.embulk.EmbulkTestRuntime;
6
+ import org.embulk.input.zendesk.RecordImporter;
7
+ import org.embulk.input.zendesk.ZendeskInputPlugin.PluginTask;
8
+ import org.embulk.input.zendesk.clients.ZendeskRestClient;
9
+ import org.embulk.input.zendesk.utils.ZendeskTestHelper;
10
+ import org.junit.Before;
11
+ import org.junit.Rule;
12
+ import org.junit.Test;
13
+ import org.mockito.ArgumentCaptor;
14
+
15
+ import java.util.Arrays;
16
+ import java.util.List;
17
+
18
+ import static org.junit.Assert.assertEquals;
19
+ import static org.junit.Assert.assertFalse;
20
+ import static org.junit.Assert.assertTrue;
21
+ import static org.mockito.ArgumentMatchers.any;
22
+ import static org.mockito.ArgumentMatchers.anyBoolean;
23
+ import static org.mockito.ArgumentMatchers.eq;
24
+ import static org.mockito.Mockito.mock;
25
+ import static org.mockito.Mockito.spy;
26
+ import static org.mockito.Mockito.times;
27
+ import static org.mockito.Mockito.verify;
28
+ import static org.mockito.Mockito.when;
29
+
30
+ public class TestZendeskUserEventService
31
+ {
32
+ private RecordImporter recordImporter;
33
+
34
+ @Rule
35
+ @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
36
+ public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
37
+ private ZendeskRestClient zendeskRestClient;
38
+ private ZendeskUserEventService zendeskUserEventService;
39
+
40
+ @Before
41
+ public void prepare()
42
+ {
43
+ zendeskRestClient = mock(ZendeskRestClient.class);
44
+ recordImporter = mock(RecordImporter.class);
45
+ }
46
+
47
+ @Test
48
+ public void testGetData()
49
+ {
50
+ setup();
51
+
52
+ JsonNode jsonNode = zendeskUserEventService.getDataFromPath("https://abc.zendesk.com/api/sunshine/objects/records?type=user&per_page=1000", 0, true, 0);
53
+ assertFalse(jsonNode.isNull());
54
+ assertTrue(jsonNode.has("data"));
55
+ assertTrue(jsonNode.get("data").isArray());
56
+ }
57
+
58
+ @Test
59
+ public void testAddRecordToImporterInPreviewMode()
60
+ {
61
+ setup();
62
+ ZendeskTestHelper.setPreviewMode(runtime, true);
63
+ zendeskUserEventService.addRecordToImporter(0, recordImporter);
64
+ verify(recordImporter, times(1)).addRecord(any());
65
+ }
66
+
67
+ @Test
68
+ public void testUrlForUserEvent()
69
+ {
70
+ ZendeskTestHelper.setPreviewMode(runtime, false);
71
+ setup();
72
+ JsonNode dataJsonOrganization = ZendeskTestHelper.getJsonFromFile("data/simple_organization.json");
73
+ JsonNode dataJsonUser = ZendeskTestHelper.getJsonFromFile("data/simple_user.json");
74
+ JsonNode dataJsonUserEventWithLatterTime = ZendeskTestHelper.getJsonFromFile("data/user_event_contain_latter_create_at.json");
75
+
76
+ when(zendeskRestClient.doGet(any(), any(), anyBoolean()))
77
+ .thenReturn(dataJsonOrganization.toString())
78
+ .thenReturn(dataJsonUser.toString())
79
+ .thenReturn(dataJsonUserEventWithLatterTime.toString());
80
+
81
+ String expectedURIForOrganization = "https://abc.zendesk.com/api/v2/organizations?per_page=100&page=1";
82
+ String expectedURIForUser = "https://abc.zendesk.com/api/v2/organizations/360857467053/users.json?per_page=100&page=1";
83
+ String expectedURIForUserEvent = "https://abc.zendesk.com/api/sunshine/events?identifier=support%3Auser_id%3A1194092277&start_time=2019-01-20T07%3A14%3A50Z&end_time=2019-06-20T07%3A14%3A53Z";
84
+ List<String> expectedURI = Arrays.asList(expectedURIForOrganization, expectedURIForUser, expectedURIForUserEvent);
85
+
86
+ zendeskUserEventService.addRecordToImporter(0, recordImporter);
87
+ ArgumentCaptor<String> uri = ArgumentCaptor.forClass(String.class);
88
+ verify(zendeskRestClient, times(3)).doGet(uri.capture(), any(), anyBoolean());
89
+ assertEquals(expectedURI, uri.getAllValues());
90
+ }
91
+
92
+ @Test
93
+ public void testAddRecordToImporterInNonPreviewMode()
94
+ {
95
+ ZendeskTestHelper.setPreviewMode(runtime, false);
96
+ PluginTask task = setup();
97
+
98
+ JsonNode dataJsonOrganization = ZendeskTestHelper.getJsonFromFile("data/organization.json");
99
+ JsonNode dataJsonUser = ZendeskTestHelper.getJsonFromFile("data/simple_user.json");
100
+ JsonNode dataJsonUserEvent = ZendeskTestHelper.getJsonFromFile("data/user_event.json");
101
+
102
+ // 2 organizations but return the same user.
103
+ when(zendeskRestClient.doGet(eq("https://abc.zendesk.com/api/v2/organizations?per_page=100&page=1"), eq(task), eq(false)))
104
+ .thenReturn(dataJsonOrganization.toString());
105
+ when(zendeskRestClient.doGet(eq("https://abc.zendesk.com/api/v2/organizations/360857467053/users.json?per_page=100&page=1"), eq(task), eq(false)))
106
+ .thenReturn(dataJsonUser.toString());
107
+ when(zendeskRestClient.doGet(eq("https://abc.zendesk.com/api/v2/organizations/360857467055/users.json?per_page=100&page=1"), eq(task), eq(false)))
108
+ .thenReturn(dataJsonUser.toString());
109
+ when(zendeskRestClient.doGet(eq("https://abc.zendesk.com/api/sunshine/events?identifier=support%3Auser_id%3A1194092277&start_time=2019-01-20T07%3A14%3A50Z&end_time=2019-06-20T07%3A14%3A53Z"), eq(task), eq(false)))
110
+ .thenReturn(dataJsonUserEvent.toString());
111
+
112
+ zendeskUserEventService.addRecordToImporter(0, recordImporter);
113
+ // non dedup
114
+ verify(recordImporter, times(2)).addRecord(any());
115
+ }
116
+
117
+ @Test
118
+ public void testAddRecordToImporterWithDuplicateUser()
119
+ {
120
+ ZendeskTestHelper.setPreviewMode(runtime, false);
121
+ PluginTask task = ZendeskTestHelper.getConfigSource("user_events.yml")
122
+ .set("dedup", true)
123
+ .loadConfig(PluginTask.class);
124
+ setupZendeskSupportAPIService(task);
125
+
126
+ JsonNode dataJsonOrganization = ZendeskTestHelper.getJsonFromFile("data/organization.json");
127
+ JsonNode dataJsonUser = ZendeskTestHelper.getJsonFromFile("data/simple_user.json");
128
+ JsonNode dataJsonUserEvent = ZendeskTestHelper.getJsonFromFile("data/user_event.json");
129
+ // 2 organizations but return the same user.
130
+ when(zendeskRestClient.doGet(eq("https://abc.zendesk.com/api/v2/organizations?per_page=100&page=1"), eq(task), eq(false)))
131
+ .thenReturn(dataJsonOrganization.toString());
132
+ when(zendeskRestClient.doGet(eq("https://abc.zendesk.com/api/v2/organizations/360857467053/users.json?per_page=100&page=1"), eq(task), eq(false)))
133
+ .thenReturn(dataJsonUser.toString());
134
+ when(zendeskRestClient.doGet(eq("https://abc.zendesk.com/api/v2/organizations/360857467055/users.json?per_page=100&page=1"), eq(task), eq(false)))
135
+ .thenReturn(dataJsonUser.toString());
136
+ when(zendeskRestClient.doGet(eq("https://abc.zendesk.com/api/sunshine/events?identifier=support%3Auser_id%3A1194092277&start_time=2019-01-20T07%3A14%3A50Z&end_time=2019-06-20T07%3A14%3A53Z"), eq(task), eq(false)))
137
+ .thenReturn(dataJsonUserEvent.toString());
138
+
139
+ zendeskUserEventService.addRecordToImporter(0, recordImporter);
140
+
141
+ // expected to call fetchUserEvent only one time
142
+ verify(recordImporter, times(1)).addRecord(any());
143
+ }
144
+
145
+ private void setupZendeskSupportAPIService(PluginTask task)
146
+ {
147
+ zendeskUserEventService = spy(new ZendeskUserEventService(task));
148
+ when(zendeskUserEventService.getZendeskRestClient()).thenReturn(zendeskRestClient);
149
+ }
150
+
151
+ private PluginTask setup()
152
+ {
153
+ PluginTask task = ZendeskTestHelper.getConfigSource("user_events.yml")
154
+ .loadConfig(PluginTask.class);
155
+ setupZendeskSupportAPIService(task);
156
+ return task;
157
+ }
158
+ }