embulk-input-google_spreadsheets 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +12 -0
  4. data/CHANGELOG.md +67 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +94 -0
  8. data/Rakefile +13 -0
  9. data/embulk-input-google_spreadsheets.gemspec +24 -0
  10. data/example/config_authorized_user.yml +19 -0
  11. data/example/config_authorized_user.yml.liquid +25 -0
  12. data/example/config_authorized_user_emoji_worksheet.yml +19 -0
  13. data/example/config_authorized_user_empty_rows_appears_at_the_same_as_max_fetch_rows.yml +20 -0
  14. data/example/config_authorized_user_large_data.yml +19 -0
  15. data/example/config_authorized_user_no_data.yml +18 -0
  16. data/example/config_service_account.yml +19 -0
  17. data/example/config_service_account_emoji_worksheet.yml +19 -0
  18. data/example/config_service_account_empty_rows_appears_at_the_same_as_max_fetch_rows.yml +20 -0
  19. data/example/config_service_account_large_data.yml +19 -0
  20. data/example/config_service_account_no_data.yml +18 -0
  21. data/example/setup_authorized_user_credentials.rb +34 -0
  22. data/lib/embulk/input/google_spreadsheets.rb +182 -0
  23. data/lib/embulk/input/google_spreadsheets/auth.rb +63 -0
  24. data/lib/embulk/input/google_spreadsheets/error.rb +36 -0
  25. data/lib/embulk/input/google_spreadsheets/pager.rb +107 -0
  26. data/lib/embulk/input/google_spreadsheets/pager_util.rb +28 -0
  27. data/lib/embulk/input/google_spreadsheets/record_typecaster.rb +73 -0
  28. data/lib/embulk/input/google_spreadsheets/spreadsheets_client.rb +75 -0
  29. data/lib/embulk/input/google_spreadsheets/spreadsheets_url_util.rb +23 -0
  30. data/lib/embulk/input/google_spreadsheets/typecast/base.rb +62 -0
  31. data/lib/embulk/input/google_spreadsheets/typecast/loose_typecast.rb +84 -0
  32. data/lib/embulk/input/google_spreadsheets/typecast/minimal_typecast.rb +109 -0
  33. data/lib/embulk/input/google_spreadsheets/typecast/strict_typecast.rb +236 -0
  34. data/lib/embulk/input/google_spreadsheets/typecast/timestamp_format_util.rb +29 -0
  35. data/lib/embulk/input/google_spreadsheets/typecast_factory.rb +34 -0
  36. data/test/assert_embulk_nothing_raised.rb +11 -0
  37. data/test/assert_embulk_raise.rb +11 -0
  38. data/test/dummy.key +27 -0
  39. data/test/helper.rb +21 -0
  40. data/test/test_auth.rb +82 -0
  41. data/test/test_configure.rb +155 -0
  42. data/test/test_loose_typecast.rb +194 -0
  43. data/test/test_minimal_typecast.rb +616 -0
  44. data/test/test_pager_util.rb +24 -0
  45. data/test/test_run_examples.rb +125 -0
  46. data/test/test_spreadsheets_client.rb +87 -0
  47. data/test/test_spreadsheets_url_util.rb +23 -0
  48. data/test/test_strict_typecast.rb +666 -0
  49. data/test/test_typecast_factory.rb +36 -0
  50. metadata +220 -0
@@ -0,0 +1,236 @@
1
+ require 'time_with_zone'
2
+ require_relative 'base'
3
+ require_relative 'timestamp_format_util'
4
+
5
+ module Embulk
6
+ module Input
7
+ class GoogleSpreadsheets < InputPlugin
8
+ module Typecast
9
+ class StrictTypecast < Base
10
+ # It has assumed that argument `value` is an instance of any of the below classes.
11
+ # NilClass
12
+ # String
13
+ # TrueClass
14
+ # FalseClass
15
+ # Integer
16
+ # Float
17
+ # Array
18
+ # Hash
19
+ # Time
20
+
21
+ def as_string(value)
22
+ return nil if null_string?(value)
23
+
24
+ case value
25
+ when nil
26
+ nil
27
+ when String
28
+ value
29
+ when TrueClass
30
+ value.to_s
31
+ when FalseClass
32
+ value.to_s
33
+ when Integer
34
+ value.to_s
35
+ when Float
36
+ value.to_s
37
+ when Array
38
+ value.to_json
39
+ when Hash
40
+ value.to_json
41
+ when Time
42
+ # TODO: support Time class
43
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Time to String: \"#{value}\""
44
+ else
45
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast #{value.class} to String: \"#{value}\""
46
+ end
47
+ end
48
+
49
+ def as_long(value)
50
+ return nil if null_string?(value)
51
+
52
+ # `to_i` issue incorrect typecast, so use Integer()
53
+ # example
54
+ # [1] pry(main)> '111:222:333'.to_i
55
+ # => 111
56
+ # [2] pry(main)> Integer('111:222:333')
57
+ # ArgumentError: invalid value for Integer(): "111:222:333"
58
+ # from (pry):2:in `Integer'
59
+ case value
60
+ when nil
61
+ nil
62
+ when String
63
+ return nil if value.is_a?(String) and value.empty?
64
+ begin
65
+ Integer(value)
66
+ rescue ArgumentError => e
67
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: #{e}"
68
+ end
69
+ when TrueClass
70
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast true to Integer: \"#{value}\""
71
+ when FalseClass
72
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast false to Integer: \"#{value}\""
73
+ when Integer
74
+ value
75
+ when Float
76
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Float to Integer: \"#{value}\""
77
+ when Array
78
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Array to Integer: \"#{value}\""
79
+ when Hash
80
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Hash to Integer: \"#{value}\""
81
+ when Time
82
+ value.to_i
83
+ else
84
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast #{value.class} to Integer: \"#{value}\""
85
+ end
86
+ end
87
+
88
+ def as_double(value)
89
+ return nil if null_string?(value)
90
+
91
+ # `to_f` issue incorrect typecast, so use Float()
92
+ # example
93
+ # [1] pry(main)> '111:222:333'.to_f
94
+ # => 111.0
95
+ # [2] pry(main)> Float('111:222:333')
96
+ # ArgumentError: invalid value for Float(): "111:222:333"
97
+ # from (pry):2:in `Float'
98
+ case value
99
+ when nil
100
+ nil
101
+ when String, Integer
102
+ return nil if value.is_a?(String) and value.empty?
103
+ begin
104
+ Float(value)
105
+ rescue ArgumentError => e
106
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: #{e}"
107
+ end
108
+ when TrueClass
109
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast true to Float: \"#{value}\""
110
+ when FalseClass
111
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast false to Float: \"#{value}\""
112
+ # when Integer then ...
113
+ # => merge with String case
114
+ when Float
115
+ value
116
+ when Array
117
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Array to Float: \"#{value}\""
118
+ when Hash
119
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Hash to Float: \"#{value}\""
120
+ when Time
121
+ value.to_f
122
+ else
123
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast #{value.class} to Float: \"#{value}\""
124
+ end
125
+ end
126
+
127
+ BOOLEAN_TRUE_VALUES = %w(yes y true t 1)
128
+ BOOLEAN_FALSE_VALUES = %w(no n false f 0)
129
+
130
+ def as_boolean(value)
131
+ return nil if null_string?(value)
132
+
133
+ case value
134
+ when nil
135
+ nil
136
+ when String, Integer
137
+ return nil if value.is_a?(String) and value.empty?
138
+ value = value.to_s unless value.is_a?(String)
139
+ return true if BOOLEAN_TRUE_VALUES.include?(value.downcase)
140
+ return false if BOOLEAN_FALSE_VALUES.include?(value.downcase)
141
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast '#{value}' to a boolean value." \
142
+ " A boolean value must be one of #{BOOLEAN_TRUE_VALUES + BOOLEAN_FALSE_VALUES}: \"#{value}\""
143
+ when TrueClass
144
+ true
145
+ when FalseClass
146
+ false
147
+ # when Integer then ... => merge with String case
148
+ when Float
149
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Float to a boolean value: \"#{value}\""
150
+ when Array
151
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Array to a boolean value: \"#{value}\""
152
+ when Hash
153
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Hash to a boolean value: \"#{value}\""
154
+ when Time
155
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Time to String: \"#{value}\""
156
+ else
157
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast #{value.class} to a boolean value: \"#{value}\""
158
+ end
159
+ end
160
+
161
+ def as_timestamp(value, timestamp_format = nil, timezone = nil)
162
+ return nil if null_string?(value)
163
+
164
+ case value
165
+ when nil
166
+ nil
167
+ when String, Integer, Float
168
+ return nil if value.is_a?(String) and value.empty?
169
+ value = value.to_s unless value.is_a?(String)
170
+ begin
171
+ if timestamp_format and TimestampFormatUtil.timezone_format?(timestamp_format)
172
+ Time.strptime(value, timestamp_format)
173
+ elsif timestamp_format and timezone
174
+ TimeWithZone.strptime_with_zone(value, timestamp_format, timezone)
175
+ elsif timezone
176
+ TimeWithZone.parse_with_zone(value, timezone)
177
+ elsif timestamp_format
178
+ Time.strptime(value, timestamp_format)
179
+ else
180
+ Time.parse(value)
181
+ end
182
+ rescue ArgumentError => e
183
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast #{value.class} to Time: \"#{value}\" because of '#{e}'"
184
+ end
185
+ when TrueClass
186
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast true to Time: \"#{value}\""
187
+ when FalseClass
188
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast false to Time: \"#{value}\""
189
+ # when Integer
190
+ # ... => merge with String case
191
+ # when Float
192
+ # ... => merge with String case
193
+ when Array
194
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Array to Time: \"#{value}\""
195
+ when Hash
196
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Hash to Time: \"#{value}\""
197
+ when Time
198
+ value
199
+ else
200
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast #{value.class} to Time: \"#{value}\""
201
+ end
202
+ end
203
+
204
+ def as_json(value)
205
+ return nil if null_string?(value)
206
+
207
+ # NOTE: This method must do `JSON.parse` if `value` is String. ref. https://github.com/embulk/embulk/issues/499
208
+ case value
209
+ when nil, Array, Hash
210
+ value
211
+ when String
212
+ begin
213
+ JSON.parse(value)
214
+ rescue JSON::ParserError => e
215
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast #{value.class} to JSON: \"#{value}\" because of '#{e}'"
216
+ end
217
+ # when TrueClass then ... => merge with Time case
218
+ # when FalseClass then ... => merge with Time case
219
+ # when Integer then ... => merge with Time case
220
+ # when Float then ... => merge with Time case
221
+ # when Array then ... => merge with nil case
222
+ # when Hash then ... => merge with nil case
223
+ when TrueClass, FalseClass, Integer, Float, Array, Hash, Time
224
+ # TODO: support Time class. Now call Exception to avoid format/timezone trouble.
225
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast Time to JSON: \"#{value}\""
226
+
227
+ else
228
+ raise TypecastError.new "`embulk-input-google_spreadsheets`: cannot typecast #{value.class} to JSON: \"#{value}\""
229
+ end
230
+ end
231
+
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,29 @@
1
+ module Embulk
2
+ module Input
3
+ class GoogleSpreadsheets < InputPlugin
4
+ module Typecast
5
+ module TimestampFormatUtil
6
+
7
+ def self.timezone_format?(format)
8
+ @cache ||= {}
9
+ return @cache[format.dup] if @cache.has_key?(format)
10
+ @cache[format] = tz_regexp === format
11
+ end
12
+
13
+ private
14
+
15
+ def self.tz_regexp
16
+ # Time zone:
17
+ # %z - Time zone as hour and minute offset from UTC (e.g. +0900)
18
+ # %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
19
+ # %::z - hour, minute and second offset from UTC (e.g. +09:00:00)
20
+ # %Z - Abbreviated time zone name or similar information. (OS dependent)
21
+ #
22
+ # ref. https://docs.ruby-lang.org/en/2.3.0/Time.html#method-i-strftime
23
+ @tz_regexp ||= %r{(?:\A|[^%]|(?:%%)+)%(?::?:?z|Z)}
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'error'
2
+
3
+ module Embulk
4
+ module Input
5
+ class GoogleSpreadsheets < InputPlugin
6
+ module TypecastFactory
7
+ def self.create(type, task)
8
+ raise GoogleSpreadsheets::ConfigError.new("`embulk-input-google_spreadsheets`: unknown typecast '#{type}'") if type.nil? or !type.is_a?(String)
9
+
10
+ type = type.downcase
11
+ path = build_typecast_class_path(type)
12
+ raise GoogleSpreadsheets::ConfigError.new("`embulk-input-google_spreadsheets`: Typecast class path does not exist '#{path}'") unless File.exist?(path)
13
+
14
+ require path
15
+ typecast_class(type).new(task)
16
+ end
17
+
18
+ private
19
+
20
+ def self.typecast_class(type)
21
+ Object.const_get("Embulk::Input::GoogleSpreadsheets::Typecast::#{camelize(type)}Typecast")
22
+ end
23
+
24
+ def self.build_typecast_class_path(type)
25
+ File.expand_path("typecast/#{type}_typecast.rb", __dir__)
26
+ end
27
+
28
+ def self.camelize(snake)
29
+ snake.split('_').map{|w| w[0] = w[0].upcase; w}.join
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ module AssertEmbulkNothingRaised
2
+ # NOTE: assert_raise(TypecastError) do ... end can't detect correctly
3
+ def assert_embulk_nothing_raised(&block)
4
+ begin
5
+ yield
6
+ assert true
7
+ rescue => e
8
+ assert_equal(nil, e)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module AssertEmbulkRaise
2
+ # NOTE: assert_raise(TypecastError) do ... end can't detect correctly
3
+ def assert_embulk_raise(klass, &block)
4
+ begin
5
+ yield
6
+ assert false
7
+ rescue => e
8
+ assert e.is_a?(klass), "expect: #{klass.name}, actual: #{e.class.name}, message: #{e}"
9
+ end
10
+ end
11
+ end
data/test/dummy.key ADDED
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpgIBAAKCAQEApmXpbr2WNslz+T881vt8uljjBtcJR8eu0UVcGfLjdZ+sn86z
3
+ HMJgzKUlV5Y8GFT2ktgcznAM/Tn83XsKbOLKfdutdnRHQK/bG4Qj7QxI1TiEbJ8y
4
+ c8EWdO8GvFQXkKSlL26U/t8tPgnFrYKt5C/XNvVL3vPEWS9MtJk903llWhRueXJ8
5
+ iOFMKWq50fIr28gzDnzXqwErhzdDuxI2FWHcjXI20eWMg/uHG8m0OfHDZhcsOlri
6
+ +SXX+TkCwEeyUak2WqPCA+HzlNJRGyphgQIMixI8ZAnZ6vmz4coD5yXNRGOzAhq1
7
+ 86s/ajOAFnSOVN98SutvkrgY9UlywPv+5UVxnwIDAQABAoIBAQCeVt3xlhDJ45sr
8
+ M8TWIguHW6v1R0y6dEZjNyg0PQ+7Tw06KLwCAumP8xp8pSZcVQUpqOKIgtGpabO4
9
+ oivCf3EGoLMIxA9Fe9H49h4lpQntc9F3d2nQAo43CXkUXsTpy/KwFv9LJN3taekk
10
+ efS07d1Sm8rtxnMyFrNcK3JMuPj75GmdSHPGnBth/EUMoNzE4FiTUJaDg/DrXHg/
11
+ zxIW7H+vVKEnlhExp8vX4VXgXJJ1J4woXAD1h2RneV2zHu/OsXI5prBbSUdR2jSw
12
+ obZqF2XFpBvZOOuYWQ53kJB1vqLWODb14Bp7okfpqA9QSM52tzTJjXYGpgd0lhGq
13
+ vHfulyCJAoGBAN0Uw9slMitG3TlabKdCbzKHhw8izuyFpfPU+NU+PeKZo4yN5iRG
14
+ jr5S+VlmavqzNyhgG6bh1f2e95Tygcu7CKMTDG6m4s71iZ+yr+yN/bX07DwSERor
15
+ q3NtYxLtvAdEUkpAxLTDZXzYDYWXKOkslV8hNZJXZiQX98KdkEkljnbdAoGBAMCu
16
+ FVZVVm186yQLE3myfHemyiGoyLNivEXDL0/L5P/FFTlS7CwMq3+ZBdPWuPKi8pjb
17
+ K4NUxDOAWMgTJzKcQRCNLez470l9GGp+tIvlo7gtt8BVkIL0jIZ92xV7nGskDV1z
18
+ HnqdkJ/v8Y2/CIZ9q7Q+iLcM+Xf/BNuccIwInXyrAoGBAL/r797FmpjhKtlIO3yz
19
+ +o5WAxRLtnCz0Q4su1t7bgPSNp2k7b5eFjr5EwfeFk7O17pQPJESCk/i+bEvGSiA
20
+ lI3k0m0YqVra4v9lAr4Lwc188rtvP7OFZ5CLzG85PHref8WAFoOKAQdxE8P+JoDN
21
+ uFpeHQCOqNf6ipZDbGdjmBptAoGBAL3H+b5CadGH0/d5bWJV2mDkCH3kyGJgIv83
22
+ xBb9xn3ieggvU+4DQLx6VZIVEa/zra2/WnmN+X6csVXH/7jKzQ9nb0/U1aP1siHa
23
+ 0SxmML8NUMsBvEgwZWVm+26KhUPGi996rw+ouLW/2ZV7DwOhLolnerOJ9QIrTnac
24
+ /QIAzlXnAoGBAMq/PA22fsGGyJwtKoxJiFwm6myb9q4dx7CsRUW8FivXXa8IBV6K
25
+ 8TvzytIGA9SjIRHQR9wDOlxyO7JE5ndEwBIsPesARvcRdrukN7UWorT5y33KRe8m
26
+ bd54ICAxK+uNVWBv2xaM6V9hFdzeYZ8McZvlht4AqDmkHu/nsTYMeLci
27
+ -----END RSA PRIVATE KEY-----
data/test/helper.rb ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'test/unit/rr'
5
+
6
+ ENV['TZ'] = 'JST-9'
7
+
8
+ require 'embulk'
9
+ Embulk.setup
10
+ Embulk.logger = Embulk::Logger.new('/dev/null')
11
+
12
+ APP_ROOT = File.expand_path('../', __dir__)
13
+ EXAMPLE_ROOT = File.join(APP_ROOT, 'example')
14
+ TEST_ROOT = File.join(APP_ROOT, 'test')
15
+ JSON_KEYFILE_SERVICE_ACCOUNT = File.join(EXAMPLE_ROOT, 'service_account_credentials.json')
16
+ JSON_KEYFILE_AUTHORIZED_USER = File.join(EXAMPLE_ROOT, 'authorized_user_credentials.json')
17
+ TEST_SPREADSHEETS_URL = 'https://docs.google.com/spreadsheets/d/1Cxz-LudQuhRAGZL8mBoHs6mRnpjODpyF4Rwc5UYoV1E/edit#gid=0'
18
+ TEST_SPREADSHEETS_ID = '1Cxz-LudQuhRAGZL8mBoHs6mRnpjODpyF4Rwc5UYoV1E'
19
+ TEST_WORKSHEET_TITLE = 'sheet1'
20
+ TEST_WORKSHEET_TITLE_MULTI_BYTE = '日本語(japanese)'
21
+ DUMMY_RSA_KEY = File.expand_path('dummy.key', __dir__) # openssl genrsa 2048 > dummy.key
data/test/test_auth.rb ADDED
@@ -0,0 +1,82 @@
1
+ require_relative 'helper'
2
+ require 'embulk/input/google_spreadsheets'
3
+ require_relative 'assert_embulk_raise'
4
+ require_relative 'assert_embulk_nothing_raised'
5
+
6
+ module Embulk
7
+ class Input::GoogleSpreadsheets < InputPlugin
8
+
9
+ class TestAuth < Test::Unit::TestCase
10
+
11
+ include AssertEmbulkRaise
12
+ include AssertEmbulkNothingRaised
13
+
14
+ sub_test_case 'authorized_user' do
15
+ unless File.exist?(JSON_KEYFILE_AUTHORIZED_USER)
16
+ puts "#{JSON_KEYFILE_AUTHORIZED_USER} is not found. Skip correct cases authorized_user"
17
+ else
18
+ test 'correct json_keyfile' do
19
+ task = {
20
+ 'auth_method' => 'authorized_user',
21
+ 'json_keyfile' => File.read(JSON_KEYFILE_AUTHORIZED_USER)
22
+ }
23
+ assert_embulk_nothing_raised do
24
+ Auth.new(task).authenticate.fetch_access_token!
25
+ end
26
+ end
27
+ end
28
+
29
+ test 'incorrect json_keyfile' do
30
+ task = {
31
+ 'auth_method' => 'authorized_user',
32
+ 'json_keyfile' => '{"client_id":"hoge", "client_secret":"fuga","refresh_token":"hogo"}'
33
+ }
34
+ assert_embulk_raise Signet::AuthorizationError do
35
+ Auth.new(task).authenticate.fetch_access_token!
36
+ end
37
+ end
38
+ end
39
+
40
+ sub_test_case 'service_account' do
41
+ unless File.exist?(JSON_KEYFILE_SERVICE_ACCOUNT)
42
+ puts "#{JSON_KEYFILE_SERVICE_ACCOUNT} is not found. Skip correct cases service_account"
43
+ else
44
+ test 'correct json_keyfile' do
45
+ task = {
46
+ 'auth_method' => 'service_account',
47
+ 'json_keyfile' => File.read(JSON_KEYFILE_SERVICE_ACCOUNT)
48
+ }
49
+ assert_embulk_nothing_raised do
50
+ Auth.new(task).authenticate.fetch_access_token!
51
+ end
52
+ end
53
+ end
54
+
55
+ test 'incorrect json_keyfile' do
56
+ dummy_rsa_key = File.read(DUMMY_RSA_KEY).gsub("\n", '\n')
57
+ task = {
58
+ 'auth_method' => 'service_account',
59
+ 'json_keyfile' => '{"client_id":"hoge", "client_secret":"fuga","client_email":"hogo","private_key":"' + dummy_rsa_key + '"}'
60
+ }
61
+ assert_embulk_raise Signet::AuthorizationError do
62
+ Auth.new(task).authenticate.fetch_access_token!
63
+ end
64
+ end
65
+ end
66
+
67
+ # TODO: compute_engine cases
68
+ # TODO: application_default cases
69
+
70
+ sub_test_case 'ConfigError' do
71
+ test 'invalid auth_method' do
72
+ task = {
73
+ 'auth_methqd' => 'hoge'
74
+ }
75
+ assert_embulk_raise ConfigError do
76
+ Auth.new(task).authenticate
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end