embulk-input-kintone 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68954eaff6b8344ffcddf296dfaf47a73882a315
4
- data.tar.gz: '0587da14d8658b81f0f94ed9a2f26475eb2c5595'
3
+ metadata.gz: 7228024b39d9a99ed12bb46ed0533fbf0e8bc203
4
+ data.tar.gz: 79da56d30429a42c0f286c6e898f9f67b8ee17c1
5
5
  SHA512:
6
- metadata.gz: 941e7ed35a81853b42e41da31d78dd0afb3ccf8a27f4f1f6b23e4308caca10f36d705802eaf9d3a21a902f94a4dde3a9548cc519d524b360bfb842a59d2c7337
7
- data.tar.gz: 48a62cd9aeccf5d307a971a1da9f9e38a350513569be5a3a5218128b3418b6c4414f3a889450f027b9a3272bc90f8a337144571379d41e175c812e7ccf366ca7
6
+ metadata.gz: 8dd98237c2e4d4141466ff8f1405eb3c36e4b6f531f0fa3571abc17336a72c8f04cbcc8eecfa305d0c25470c4ae15cdb142d259d74c6c6867c82b3b81f69050d
7
+ data.tar.gz: ba3f6ca0f421e40119a68f4b076085d2b405e4663a2a733ad49bc7147fac4be05e835ad48bcc853088767f565576f712b6092a800b68f4f64963b9e43e036367
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: java
2
+ jdk:
3
+ - oraclejdk8
4
+ - openjdk8
5
+ script:
6
+ - ./gradlew --info check
7
+ dist: trusty
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Kintone input plugin for Embulk
2
+ [![Build Status](https://travis-ci.org/trocco-io/embulk-input-kintone.svg?branch=master)](https://travis-ci.org/trocco-io/embulk-input-kintone)
2
3
 
3
4
  ## Overview
4
5
  Kintone input plugin for Embulk loads app records from Kintone.
@@ -13,7 +14,6 @@ embulk 0.9 is only supported due to the dependency of kintone-java-sdk 0.4.0, wh
13
14
  - [ ] Guess
14
15
  - [ ] Subtable data type support
15
16
  - [ ] field name mapping
16
- - [ ] timestamp_format in fields
17
17
  - [ ] handle certification fot authentication
18
18
 
19
19
  ## Configuration
@@ -30,6 +30,7 @@ embulk 0.9 is only supported due to the dependency of kintone-java-sdk 0.4.0, wh
30
30
  - **fields** (required)
31
31
  - **name** the field code of Kintone app record will be retrieved.
32
32
  - **type** Column values are converted to this embulk type. Available values options are: boolean, long, double, string, json, timestamp)
33
+ - **format** Format of the timestamp if type is timestamp. The format for kintone DATETIME is `%Y-%m-%dT%H:%M:%S%z`.
33
34
 
34
35
  Kintone API has the limitation, therefore this plugin also faces it. See [official documentation](https://developer.kintone.io/hc/en-us/articles/212495188/)
35
36
 
@@ -66,6 +67,7 @@ in:
66
67
  - {name: Time, type: string}
67
68
  - {name: Created_datatime, type: string}
68
69
  - {name: foo, type: string}
70
+ - {name: datetime, type: timestamp, format: '%Y-%m-%dT%H:%M:%S%z'}
69
71
  ```
70
72
 
71
73
  ## Build
data/build.gradle CHANGED
@@ -13,7 +13,7 @@ configurations {
13
13
  provided
14
14
  }
15
15
 
16
- version = "0.1.1"
16
+ version = "0.1.2"
17
17
 
18
18
  sourceCompatibility = 1.8
19
19
  targetCompatibility = 1.8
@@ -26,6 +26,8 @@ dependencies {
26
26
  testCompile "junit:junit:4.+"
27
27
  testCompile 'org.embulk:embulk-standards:0.9.12'
28
28
  testCompile 'org.embulk:embulk-test:0.9.12'
29
+ testCompile "org.mockito:mockito-core:1.+"
30
+ testCompile "org.embulk:embulk-core:0.9.12:tests"
29
31
  }
30
32
 
31
33
  task classpath(type: Copy, dependsOn: ["jar"]) {
data/gradlew.bat CHANGED
@@ -1,84 +1,84 @@
1
- @if "%DEBUG%" == "" @echo off
2
- @rem ##########################################################################
3
- @rem
4
- @rem Gradle startup script for Windows
5
- @rem
6
- @rem ##########################################################################
7
-
8
- @rem Set local scope for the variables with windows NT shell
9
- if "%OS%"=="Windows_NT" setlocal
10
-
11
- set DIRNAME=%~dp0
12
- if "%DIRNAME%" == "" set DIRNAME=.
13
- set APP_BASE_NAME=%~n0
14
- set APP_HOME=%DIRNAME%
15
-
16
- @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17
- set DEFAULT_JVM_OPTS=
18
-
19
- @rem Find java.exe
20
- if defined JAVA_HOME goto findJavaFromJavaHome
21
-
22
- set JAVA_EXE=java.exe
23
- %JAVA_EXE% -version >NUL 2>&1
24
- if "%ERRORLEVEL%" == "0" goto init
25
-
26
- echo.
27
- echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28
- echo.
29
- echo Please set the JAVA_HOME variable in your environment to match the
30
- echo location of your Java installation.
31
-
32
- goto fail
33
-
34
- :findJavaFromJavaHome
35
- set JAVA_HOME=%JAVA_HOME:"=%
36
- set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
-
38
- if exist "%JAVA_EXE%" goto init
39
-
40
- echo.
41
- echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42
- echo.
43
- echo Please set the JAVA_HOME variable in your environment to match the
44
- echo location of your Java installation.
45
-
46
- goto fail
47
-
48
- :init
49
- @rem Get command-line arguments, handling Windows variants
50
-
51
- if not "%OS%" == "Windows_NT" goto win9xME_args
52
-
53
- :win9xME_args
54
- @rem Slurp the command line arguments.
55
- set CMD_LINE_ARGS=
56
- set _SKIP=2
57
-
58
- :win9xME_args_slurp
59
- if "x%~1" == "x" goto execute
60
-
61
- set CMD_LINE_ARGS=%*
62
-
63
- :execute
64
- @rem Setup the command line
65
-
66
- set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67
-
68
- @rem Execute Gradle
69
- "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70
-
71
- :end
72
- @rem End local scope for the variables with windows NT shell
73
- if "%ERRORLEVEL%"=="0" goto mainEnd
74
-
75
- :fail
76
- rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77
- rem the _cmd.exe /c_ return code!
78
- if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79
- exit /b 1
80
-
81
- :mainEnd
82
- if "%OS%"=="Windows_NT" endlocal
83
-
84
- :omega
1
+ @if "%DEBUG%" == "" @echo off
2
+ @rem ##########################################################################
3
+ @rem
4
+ @rem Gradle startup script for Windows
5
+ @rem
6
+ @rem ##########################################################################
7
+
8
+ @rem Set local scope for the variables with windows NT shell
9
+ if "%OS%"=="Windows_NT" setlocal
10
+
11
+ set DIRNAME=%~dp0
12
+ if "%DIRNAME%" == "" set DIRNAME=.
13
+ set APP_BASE_NAME=%~n0
14
+ set APP_HOME=%DIRNAME%
15
+
16
+ @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17
+ set DEFAULT_JVM_OPTS=
18
+
19
+ @rem Find java.exe
20
+ if defined JAVA_HOME goto findJavaFromJavaHome
21
+
22
+ set JAVA_EXE=java.exe
23
+ %JAVA_EXE% -version >NUL 2>&1
24
+ if "%ERRORLEVEL%" == "0" goto init
25
+
26
+ echo.
27
+ echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28
+ echo.
29
+ echo Please set the JAVA_HOME variable in your environment to match the
30
+ echo location of your Java installation.
31
+
32
+ goto fail
33
+
34
+ :findJavaFromJavaHome
35
+ set JAVA_HOME=%JAVA_HOME:"=%
36
+ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
+
38
+ if exist "%JAVA_EXE%" goto init
39
+
40
+ echo.
41
+ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42
+ echo.
43
+ echo Please set the JAVA_HOME variable in your environment to match the
44
+ echo location of your Java installation.
45
+
46
+ goto fail
47
+
48
+ :init
49
+ @rem Get command-line arguments, handling Windows variants
50
+
51
+ if not "%OS%" == "Windows_NT" goto win9xME_args
52
+
53
+ :win9xME_args
54
+ @rem Slurp the command line arguments.
55
+ set CMD_LINE_ARGS=
56
+ set _SKIP=2
57
+
58
+ :win9xME_args_slurp
59
+ if "x%~1" == "x" goto execute
60
+
61
+ set CMD_LINE_ARGS=%*
62
+
63
+ :execute
64
+ @rem Setup the command line
65
+
66
+ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67
+
68
+ @rem Execute Gradle
69
+ "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70
+
71
+ :end
72
+ @rem End local scope for the variables with windows NT shell
73
+ if "%ERRORLEVEL%"=="0" goto mainEnd
74
+
75
+ :fail
76
+ rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77
+ rem the _cmd.exe /c_ return code!
78
+ if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79
+ exit /b 1
80
+
81
+ :mainEnd
82
+ if "%OS%"=="Windows_NT" endlocal
83
+
84
+ :omega
@@ -14,49 +14,54 @@ import java.util.ArrayList;
14
14
 
15
15
  public class KintoneClient {
16
16
  private final Logger logger = LoggerFactory.getLogger(KintoneClient.class);
17
- private final PluginTask task;
18
- private ArrayList<String> fields;
19
17
  private Auth kintoneAuth;
20
18
  private Record kintoneRecordManager;
21
19
  private Connection con;
22
20
 
23
- public KintoneClient(final PluginTask task) {
24
- this.task = task;
21
+ public KintoneClient(){
25
22
  this.kintoneAuth = new Auth();
23
+ }
26
24
 
27
- this.fields = new ArrayList<>();
28
- for (ColumnConfig c : task.getFields().getColumns()
29
- ) {
30
- fields.add(c.getName());
31
- }
32
- this.setAuth();
33
- if (task.getGuestSpaceId().isPresent()) {
34
- this.con = new Connection(task.getDomain(), this.kintoneAuth, task.getGuestSpaceId().or(-1));
25
+ public void validateAuth(final PluginTask task) throws ConfigException{
26
+ if (task.getUsername().isPresent() && task.getPassword().isPresent()) {
27
+ return;
28
+ } else if (task.getToken().isPresent()) {
29
+ return;
35
30
  } else {
36
- this.con = new Connection(task.getDomain(), this.kintoneAuth);
31
+ throw new ConfigException("Username and password or token must be provided");
37
32
  }
38
- this.kintoneRecordManager = new Record(con);
39
33
  }
40
34
 
41
- private void setAuth() {
35
+ public void connect(final PluginTask task) {
42
36
  if (task.getUsername().isPresent() && task.getPassword().isPresent()) {
43
37
  this.kintoneAuth.setPasswordAuth(task.getUsername().get(), task.getPassword().get());
44
38
  } else if (task.getToken().isPresent()) {
45
39
  this.kintoneAuth.setApiToken(task.getToken().get());
46
- } else {
47
- throw new ConfigException("Username and password or token must be provided");
48
40
  }
49
41
 
50
42
  if (task.getBasicAuthUsername().isPresent() && task.getBasicAuthPassword().isPresent()) {
51
43
  this.kintoneAuth.setBasicAuth(task.getBasicAuthUsername().get(),
52
44
  task.getBasicAuthPassword().get());
53
45
  }
46
+
47
+ if (task.getGuestSpaceId().isPresent()) {
48
+ this.con = new Connection(task.getDomain(), this.kintoneAuth, task.getGuestSpaceId().or(-1));
49
+ } else {
50
+ this.con = new Connection(task.getDomain(), this.kintoneAuth);
51
+ }
52
+ this.kintoneRecordManager = new Record(con);
54
53
  }
55
54
 
56
- public GetRecordsResponse getResponse() {
55
+
56
+ public GetRecordsResponse getResponse(final PluginTask task) {
57
+ ArrayList<String> fields = new ArrayList<>();
58
+ for (ColumnConfig c : task.getFields().getColumns()
59
+ ) {
60
+ fields.add(c.getName());
61
+ }
57
62
  try {
58
63
  return kintoneRecordManager.getAllRecordsByQuery(
59
- this.task.getAppId(), this.task.getQuery().or(""), this.fields);
64
+ task.getAppId(), task.getQuery().or(""), fields);
60
65
  } catch (Exception e) {
61
66
  throw new RuntimeException(e);
62
67
  }
@@ -16,7 +16,7 @@ import org.slf4j.LoggerFactory;
16
16
  import com.google.gson.JsonElement;
17
17
 
18
18
  public class KintoneInputColumnVisitor implements ColumnVisitor {
19
- private static final String DEFAULT_TIMESTAMP_PATTERN = "%Y-%m-%dT%H:%M:%S.%L%z";
19
+ private static final String DEFAULT_TIMESTAMP_PATTERN = "%Y-%m-%dT%H:%M:%S%z";
20
20
  private final Logger logger = LoggerFactory.getLogger(KintoneInputColumnVisitor.class);
21
21
 
22
22
  private final PageBuilder pageBuilder;
@@ -3,6 +3,7 @@ package org.embulk.input.kintone;
3
3
  import java.util.HashMap;
4
4
  import java.util.List;
5
5
 
6
+ import com.google.common.annotations.VisibleForTesting;
6
7
  import org.embulk.config.*;
7
8
  import org.embulk.spi.Exec;
8
9
  import org.embulk.spi.PageBuilder;
@@ -51,9 +52,11 @@ public class KintoneInputPlugin
51
52
  PluginTask task = taskSource.loadTask(PluginTask.class);
52
53
 
53
54
  try {
54
- try (PageBuilder pageBuilder = new PageBuilder(Exec.getBufferAllocator(), schema, output)) {
55
- KintoneClient client = new KintoneClient(task);
56
- GetRecordsResponse response = client.getResponse();
55
+ try (PageBuilder pageBuilder = getPageBuilder(schema, output)) {
56
+ KintoneClient client = getKintoneClient();
57
+ client.validateAuth(task);
58
+ client.connect(task);
59
+ GetRecordsResponse response = client.getResponse(task);
57
60
  for (HashMap<String, FieldValue> record : response.getRecords()) {
58
61
  schema.visitColumns(new KintoneInputColumnVisitor(new KintoneAccessor(record), pageBuilder, task));
59
62
  pageBuilder.addRecord();
@@ -71,4 +74,16 @@ public class KintoneInputPlugin
71
74
  public ConfigDiff guess(ConfigSource config) {
72
75
  return Exec.newConfigDiff();
73
76
  }
77
+
78
+ @VisibleForTesting
79
+ protected PageBuilder getPageBuilder(final Schema schema, final PageOutput output)
80
+ {
81
+ return new PageBuilder(Exec.getBufferAllocator(), schema, output);
82
+ }
83
+
84
+ @VisibleForTesting
85
+ protected KintoneClient getKintoneClient(){
86
+ return new KintoneClient();
87
+ }
88
+
74
89
  }
@@ -0,0 +1,17 @@
1
+ package org.embulk.input.kintone;
2
+
3
+ import com.cybozu.kintone.client.model.app.form.FieldType;
4
+ import com.cybozu.kintone.client.model.record.field.FieldValue;
5
+
6
+ import java.util.HashMap;
7
+
8
+ public class TestHelper {
9
+ public static HashMap<String, FieldValue> addField(HashMap<String, FieldValue> record, String code, FieldType type,
10
+ Object value) {
11
+ FieldValue newField = new FieldValue();
12
+ newField.setType(type);
13
+ newField.setValue(value);
14
+ record.put(code, newField);
15
+ return record;
16
+ }
17
+ }
@@ -24,48 +24,39 @@ public class TestKintoneAccessor {
24
24
  public HashMap<String, FieldValue> createTestRecord() {
25
25
  HashMap<String, FieldValue> testRecord = new HashMap<>();
26
26
 
27
- testRecord = addField(testRecord, "文字列__1行", FieldType.SINGLE_LINE_TEXT, "test single text");
28
- testRecord = addField(testRecord, "数値", FieldType.NUMBER, this.uniqueKey);
27
+ testRecord = TestHelper.addField(testRecord, "文字列__1行", FieldType.SINGLE_LINE_TEXT, "test single text");
28
+ testRecord = TestHelper.addField(testRecord, "数値", FieldType.NUMBER, this.uniqueKey);
29
29
  this.uniqueKey += 1;
30
- testRecord = addField(testRecord, "文字列__複数行", FieldType.MULTI_LINE_TEXT, "test multi text");
31
- testRecord = addField(testRecord, "リッチエディター", FieldType.RICH_TEXT, "<div>test rich text<br /></div>");
30
+ testRecord = TestHelper.addField(testRecord, "文字列__複数行", FieldType.MULTI_LINE_TEXT, "test multi text");
31
+ testRecord = TestHelper.addField(testRecord, "リッチエディター", FieldType.RICH_TEXT, "<div>test rich text<br /></div>");
32
32
 
33
33
  ArrayList<String> selectedItemList = new ArrayList<>();
34
34
  selectedItemList.add("sample1");
35
35
  selectedItemList.add("sample2");
36
- testRecord = addField(testRecord, "チェックボックス", FieldType.CHECK_BOX, selectedItemList);
37
- testRecord = addField(testRecord, "ラジオボタン", FieldType.RADIO_BUTTON, "sample2");
38
- testRecord = addField(testRecord, "ドロップダウン", FieldType.DROP_DOWN, "sample3");
39
- testRecord = addField(testRecord, "複数選択", FieldType.MULTI_SELECT, selectedItemList);
40
- testRecord = addField(testRecord, "リンク", FieldType.LINK, "http://cybozu.co.jp/");
41
- testRecord = addField(testRecord, "日付", FieldType.DATE, "2018-01-01");
42
- testRecord = addField(testRecord, "時刻", FieldType.TIME, "12:34");
43
- testRecord = addField(testRecord, "日時", FieldType.DATETIME, "2018-01-02T02:30:00Z");
36
+ testRecord = TestHelper.addField(testRecord, "チェックボックス", FieldType.CHECK_BOX, selectedItemList);
37
+ testRecord = TestHelper.addField(testRecord, "ラジオボタン", FieldType.RADIO_BUTTON, "sample2");
38
+ testRecord = TestHelper.addField(testRecord, "ドロップダウン", FieldType.DROP_DOWN, "sample3");
39
+ testRecord = TestHelper.addField(testRecord, "複数選択", FieldType.MULTI_SELECT, selectedItemList);
40
+ testRecord = TestHelper.addField(testRecord, "リンク", FieldType.LINK, "http://cybozu.co.jp/");
41
+ testRecord = TestHelper.addField(testRecord, "日付", FieldType.DATE, "2018-01-01");
42
+ testRecord = TestHelper.addField(testRecord, "時刻", FieldType.TIME, "12:34");
43
+ testRecord = TestHelper.addField(testRecord, "日時", FieldType.DATETIME, "2018-01-02T02:30:00Z");
44
44
 
45
45
  ArrayList<Member> userList = new ArrayList<>();
46
46
  userList.add(testman1);
47
47
  userList.add(testman2);
48
- addField(testRecord, "ユーザー選択", FieldType.USER_SELECT, userList);
48
+ TestHelper.addField(testRecord, "ユーザー選択", FieldType.USER_SELECT, userList);
49
49
  ArrayList<Member> groupList = new ArrayList<>();
50
50
  groupList.add(testgroup1);
51
51
  groupList.add(testgroup2);
52
- addField(testRecord, "グループ選択", FieldType.GROUP_SELECT, groupList);
52
+ TestHelper.addField(testRecord, "グループ選択", FieldType.GROUP_SELECT, groupList);
53
53
  ArrayList<Member> orgList = new ArrayList<>();
54
54
  orgList.add(testorg1);
55
55
  orgList.add(testorg2);
56
- addField(testRecord, "組織選択", FieldType.ORGANIZATION_SELECT, orgList);
56
+ TestHelper.addField(testRecord, "組織選択", FieldType.ORGANIZATION_SELECT, orgList);
57
57
  return testRecord;
58
58
  }
59
59
 
60
- private HashMap<String, FieldValue> addField(HashMap<String, FieldValue> record, String code, FieldType type,
61
- Object value) {
62
- FieldValue newField = new FieldValue();
63
- newField.setType(type);
64
- newField.setValue(value);
65
- record.put(code, newField);
66
- return record;
67
- }
68
-
69
60
  @Test
70
61
  public void testAccess() {
71
62
  HashMap<String, FieldValue> testRecord = createTestRecord();
@@ -7,13 +7,14 @@ import org.embulk.spi.InputPlugin;
7
7
  import org.embulk.test.TestingEmbulk;
8
8
  import org.junit.Rule;
9
9
  import org.junit.Test;
10
- import org.junit.rules.ExpectedException;
11
10
 
12
11
  import static org.junit.Assert.*;
13
12
 
14
13
  public class TestKintoneClient {
15
14
  private ConfigSource config;
15
+ private KintoneClient client = new KintoneClient();
16
16
  private static final String BASIC_RESOURCE_PATH = "org/embulk/input/kintone/";
17
+ private static final String SUCCESS_MSG = "Exception should be thrown by this";
17
18
 
18
19
  private static ConfigSource loadYamlResource(TestingEmbulk embulk, String fileName) {
19
20
  return embulk.loadYamlResource(BASIC_RESOURCE_PATH + fileName);
@@ -28,8 +29,11 @@ public class TestKintoneClient {
28
29
  public void checkClientWithUsernameAndPassword() {
29
30
  config = loadYamlResource(embulk, "base.yml");
30
31
  PluginTask task = config.loadConfig(PluginTask.class);
31
- KintoneClient client = new KintoneClient(task);
32
- assertNotNull(client);
32
+ Exception e = assertThrows(Exception.class, ()-> {
33
+ client.validateAuth(task);
34
+ throw new Exception(SUCCESS_MSG);
35
+ });
36
+ assertEquals(SUCCESS_MSG, e.getMessage());
33
37
  }
34
38
 
35
39
  @Test
@@ -38,7 +42,7 @@ public class TestKintoneClient {
38
42
  config.remove("username")
39
43
  .remove("password");
40
44
  PluginTask task = config.loadConfig(PluginTask.class);
41
- ConfigException e = assertThrows(ConfigException.class, () -> new KintoneClient(task));
45
+ ConfigException e = assertThrows(ConfigException.class, () -> client.validateAuth(task));
42
46
  assertEquals("Username and password or token must be provided", e.getMessage());
43
47
  }
44
48
 
@@ -47,7 +51,7 @@ public class TestKintoneClient {
47
51
  config = loadYamlResource(embulk, "base.yml");
48
52
  config.remove("password");
49
53
  PluginTask task = config.loadConfig(PluginTask.class);
50
- ConfigException e = assertThrows(ConfigException.class, () -> new KintoneClient(task));
54
+ ConfigException e = assertThrows(ConfigException.class, () -> client.validateAuth(task));
51
55
  assertEquals("Username and password or token must be provided", e.getMessage());
52
56
  }
53
57
 
@@ -56,9 +60,7 @@ public class TestKintoneClient {
56
60
  config = loadYamlResource(embulk, "base.yml");
57
61
  config.remove("username");
58
62
  PluginTask task = config.loadConfig(PluginTask.class);
59
- ConfigException e = assertThrows(ConfigException.class, () -> {
60
- new KintoneClient(task);
61
- });
63
+ ConfigException e = assertThrows(ConfigException.class, () -> client.validateAuth(task));
62
64
  assertEquals("Username and password or token must be provided", e.getMessage());
63
65
  }
64
66
 
@@ -69,7 +71,10 @@ public class TestKintoneClient {
69
71
  .remove("password")
70
72
  .set("token", "token");
71
73
  PluginTask task = config.loadConfig(PluginTask.class);
72
- KintoneClient client = new KintoneClient(task);
73
- assertNotNull(client);
74
+ Exception e = assertThrows(Exception.class, ()-> {
75
+ client.validateAuth(task);
76
+ throw new Exception(SUCCESS_MSG);
77
+ });
78
+ assertEquals(SUCCESS_MSG, e.getMessage());
74
79
  }
75
80
  }
@@ -1,27 +1,99 @@
1
1
  package org.embulk.input.kintone;
2
2
 
3
+ import com.cybozu.kintone.client.model.app.form.FieldType;
4
+ import com.cybozu.kintone.client.model.record.GetRecordsResponse;
5
+ import com.cybozu.kintone.client.model.record.field.FieldValue;
6
+
7
+ import org.embulk.EmbulkTestRuntime;
8
+ import org.embulk.config.ConfigDiff;
3
9
  import org.embulk.config.ConfigSource;
10
+ import org.embulk.config.TaskReport;
11
+ import org.embulk.config.TaskSource;
4
12
  import org.embulk.spi.InputPlugin;
5
-
13
+ import org.embulk.spi.Schema;
14
+ import org.embulk.spi.TestPageBuilderReader.MockPageOutput;
15
+ import org.embulk.spi.time.Timestamp;
16
+ import org.embulk.spi.time.TimestampParser;
17
+ import org.embulk.spi.util.Pages;
6
18
  import org.embulk.test.TestingEmbulk;
19
+
20
+ import org.junit.Before;
7
21
  import org.junit.Rule;
8
22
  import org.junit.Test;
9
23
 
24
+ import java.util.ArrayList;
25
+ import java.util.HashMap;
26
+ import java.util.List;
27
+ import java.util.stream.Collectors;
28
+ import java.util.stream.IntStream;
29
+
10
30
  import static org.junit.Assert.*;
31
+ import static org.mockito.Mockito.*;
11
32
 
12
33
  public class TestKintoneInputPlugin {
13
34
  private ConfigSource config;
14
35
  private static final String BASIC_RESOURCE_PATH = "org/embulk/input/kintone/";
36
+ private KintoneInputPlugin kintoneInputPlugin;
37
+ private KintoneClient kintoneClient;
38
+ private MockPageOutput output = new MockPageOutput();
39
+ private TimestampParser dateParser = TimestampParser.of("%Y-%m-%d", "UTC");
40
+ private TimestampParser timestampParser = TimestampParser.of("%Y-%m-%dT%H:%M:%S%z", "UTC");
15
41
 
16
42
  private static ConfigSource loadYamlResource(TestingEmbulk embulk, String fileName) {
17
43
  return embulk.loadYamlResource(BASIC_RESOURCE_PATH + fileName);
18
44
  }
19
45
 
46
+ @Before
47
+ public void prepare(){
48
+ kintoneInputPlugin = spy(new KintoneInputPlugin());
49
+ kintoneClient = mock(KintoneClient.class);
50
+ doReturn(kintoneClient).when(kintoneInputPlugin).getKintoneClient();
51
+ }
52
+ @Rule
53
+ public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
54
+
20
55
  @Rule
21
56
  public TestingEmbulk embulk = TestingEmbulk.builder()
22
57
  .registerPlugin(InputPlugin.class, "kintone", KintoneInputPlugin.class)
23
58
  .build();
24
59
 
60
+ @Test
61
+ public void simpleTest(){
62
+ config = loadYamlResource(embulk, "base.yml");
63
+ PluginTask task = config.loadConfig(PluginTask.class);
64
+ Schema outputSchema = task.getFields().toSchema();
65
+ GetRecordsResponse response = createSampleData();
66
+ when(kintoneClient.getResponse(any(PluginTask.class))).thenReturn(response);
67
+
68
+ ConfigDiff configDiff = kintoneInputPlugin.transaction(config, new Control());
69
+
70
+ assertTrue(configDiff.isEmpty());
71
+
72
+ List<Object[]> outputRecords = Pages.toObjects(outputSchema, output.pages);
73
+ Object[] record1 = outputRecords.get(0);
74
+
75
+ Timestamp date1 = dateParser.parse("2020-01-01");
76
+ Timestamp timestamp1 = timestampParser.parse("2020-01-01T00:00:00Z");
77
+
78
+ assertEquals(2, outputRecords.size());
79
+
80
+ assertEquals("test single text", record1[0]);
81
+ assertEquals(1L, record1[1]);
82
+ assertEquals(1.111, record1[2]);
83
+ assertEquals(date1, record1[3]);
84
+ assertEquals(timestamp1, record1[4]);
85
+
86
+ Timestamp date2 = dateParser.parse("2020-02-02");
87
+ Timestamp timestamp2 = timestampParser.parse("2020-02-02T00:00:00Z");
88
+
89
+ Object[] record2 = outputRecords.get(1);
90
+ assertEquals("test single text2", record2[0]);
91
+ assertEquals(2L, record2[1]);
92
+ assertEquals(2.222, record2[2]);
93
+ assertEquals(date2, record2[3]);
94
+ assertEquals(timestamp2, record2[4]);
95
+ }
96
+
25
97
  @Test
26
98
  public void checkDefaultConfigValues() {
27
99
  config = loadYamlResource(embulk, "base.yml");
@@ -37,4 +109,41 @@ public class TestKintoneInputPlugin {
37
109
  assertFalse(task.getQuery().isPresent());
38
110
  assertNotNull(task.getFields());
39
111
  }
112
+
113
+ private GetRecordsResponse createSampleData(){
114
+ HashMap<String, FieldValue> record1 = new HashMap<>();
115
+ HashMap<String, FieldValue> record2 = new HashMap<>();
116
+ ArrayList<HashMap<String, FieldValue>> records = new ArrayList<>();
117
+ GetRecordsResponse response = new GetRecordsResponse();
118
+
119
+ record1 = TestHelper.addField(record1, "foo", FieldType.SINGLE_LINE_TEXT, "test single text");
120
+ record1 = TestHelper.addField(record1, "bar", FieldType.NUMBER, 1);
121
+ record1 = TestHelper.addField(record1, "baz", FieldType.NUMBER, 1.111);
122
+ record1 = TestHelper.addField(record1, "date", FieldType.DATE, "2020-01-01");
123
+ record1 = TestHelper.addField(record1, "datetime", FieldType.DATE, "2020-01-01T00:00:00Z");
124
+ records.add(record1);
125
+
126
+ record2 = TestHelper.addField(record2, "foo", FieldType.SINGLE_LINE_TEXT, "test single text2");
127
+ record2 = TestHelper.addField(record2, "bar", FieldType.NUMBER, 2);
128
+ record2 = TestHelper.addField(record2, "baz", FieldType.NUMBER, 2.222);
129
+ record2 = TestHelper.addField(record2, "date", FieldType.DATE, "2020-02-02");
130
+ record2 = TestHelper.addField(record2, "datetime", FieldType.DATE, "2020-02-02T00:00:00Z");
131
+ records.add(record2);
132
+
133
+ response.setRecords(records);
134
+ response.setTotalCount(2);
135
+ return response;
136
+ }
137
+
138
+ private class Control implements InputPlugin.Control
139
+ {
140
+ @Override
141
+ public List<TaskReport> run(final TaskSource taskSource, final Schema schema, final int taskCount)
142
+ {
143
+ List<TaskReport> reports = IntStream.range(0, taskCount)
144
+ .mapToObj(i -> kintoneInputPlugin.run(taskSource, schema, i, output))
145
+ .collect(Collectors.toList());
146
+ return reports;
147
+ }
148
+ }
40
149
  }
@@ -7,3 +7,5 @@ fields:
7
7
  - {name: foo, type: string}
8
8
  - {name: bar, type: long}
9
9
  - {name: baz, type: double}
10
+ - {name: date, type: timestamp, format: '%Y-%m-%d'}
11
+ - {name: datetime, type: timestamp}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-input-kintone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - giwa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-11 00:00:00.000000000 Z
11
+ date: 2019-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -46,10 +46,11 @@ extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
48
  - ".gitignore"
49
+ - ".travis.yml"
49
50
  - LICENSE.txt
50
51
  - README.md
51
52
  - build.gradle
52
- - classpath/embulk-input-kintone-0.1.1.jar
53
+ - classpath/embulk-input-kintone-0.1.2.jar
53
54
  - classpath/gson-2.8.2.jar
54
55
  - classpath/kintone-sdk-0.4.0.jar
55
56
  - config/checkstyle/checkstyle.xml
@@ -64,6 +65,7 @@ files:
64
65
  - src/main/java/org/embulk/input/kintone/KintoneInputColumnVisitor.java
65
66
  - src/main/java/org/embulk/input/kintone/KintoneInputPlugin.java
66
67
  - src/main/java/org/embulk/input/kintone/PluginTask.java
68
+ - src/test/java/org/embulk/input/kintone/TestHelper.java
67
69
  - src/test/java/org/embulk/input/kintone/TestKintoneAccessor.java
68
70
  - src/test/java/org/embulk/input/kintone/TestKintoneClient.java
69
71
  - src/test/java/org/embulk/input/kintone/TestKintoneInputPlugin.java