embulk-input-google_spreadsheets 1.0.0

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