embulk-input-zendesk-all 0.3.7

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 (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
+ }