embulk-input-kintone 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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