copy_tuner_client 2.1.2 → 2.2.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rubocop.yml +46 -1
  4. data/CLAUDE.md +1 -0
  5. data/Gemfile +1 -0
  6. data/copy_tuner_client.gemspec +3 -3
  7. data/gemfiles/8.0.gemfile +3 -3
  8. data/gemfiles/8.1.gemfile +3 -3
  9. data/gemfiles/main.gemfile +3 -3
  10. data/lib/copy_tuner_client/cache.rb +34 -27
  11. data/lib/copy_tuner_client/client.rb +35 -23
  12. data/lib/copy_tuner_client/configuration.rb +62 -40
  13. data/lib/copy_tuner_client/copyray/rewriter.rb +1 -1
  14. data/lib/copy_tuner_client/copyray.rb +1 -0
  15. data/lib/copy_tuner_client/copyray_middleware.rb +31 -24
  16. data/lib/copy_tuner_client/dotted_hash.rb +7 -7
  17. data/lib/copy_tuner_client/engine.rb +4 -6
  18. data/lib/copy_tuner_client/helper_extension.rb +58 -54
  19. data/lib/copy_tuner_client/i18n_backend.rb +12 -14
  20. data/lib/copy_tuner_client/i18n_compat.rb +2 -1
  21. data/lib/copy_tuner_client/poller.rb +3 -4
  22. data/lib/copy_tuner_client/prefixed_logger.rb +13 -12
  23. data/lib/copy_tuner_client/process_guard.rb +29 -26
  24. data/lib/copy_tuner_client/queue_with_timeout.rb +29 -19
  25. data/lib/copy_tuner_client/rails.rb +9 -8
  26. data/lib/copy_tuner_client/request_sync.rb +26 -24
  27. data/lib/copy_tuner_client/simple_form_extention.rb +10 -6
  28. data/lib/copy_tuner_client/translation_log.rb +10 -5
  29. data/lib/copy_tuner_client/version.rb +1 -1
  30. data/lib/copy_tuner_client.rb +4 -8
  31. data/lib/tasks/copy_tuner_client_tasks.rake +14 -16
  32. data/skills/copy-tuner-to-locales-migrate-prefix/scripts/migrate_prefix.rb +14 -7
  33. data/skills/copy-tuner-to-t-migrate/scripts/migrate_tt.rb +19 -17
  34. data/spec/copy_tuner_client/cache_spec.rb +63 -57
  35. data/spec/copy_tuner_client/client_spec.rb +82 -81
  36. data/spec/copy_tuner_client/configuration_spec.rb +223 -222
  37. data/spec/copy_tuner_client/copyray/marker_spec.rb +2 -1
  38. data/spec/copy_tuner_client/copyray/rewriter_spec.rb +15 -10
  39. data/spec/copy_tuner_client/copyray_middleware_spec.rb +9 -6
  40. data/spec/copy_tuner_client/copyray_spec.rb +8 -8
  41. data/spec/copy_tuner_client/dotted_hash_spec.rb +33 -33
  42. data/spec/copy_tuner_client/helper_extension_spec.rb +47 -44
  43. data/spec/copy_tuner_client/i18n_backend_spec.rb +144 -143
  44. data/spec/copy_tuner_client/poller_spec.rb +25 -24
  45. data/spec/copy_tuner_client/prefixed_logger_spec.rb +15 -12
  46. data/spec/copy_tuner_client/process_guard_spec.rb +27 -27
  47. data/spec/copy_tuner_client/request_sync_spec.rb +51 -58
  48. data/spec/copy_tuner_client/translation_log_spec.rb +38 -24
  49. data/spec/copy_tuner_client_spec.rb +5 -6
  50. data/spec/support/client_spec_helpers.rb +1 -1
  51. data/spec/support/defines_constants.rb +3 -34
  52. data/spec/support/fake_client.rb +1 -3
  53. data/spec/support/fake_copy_tuner_app.rb +54 -62
  54. data/spec/support/fake_html_safe_string.rb +2 -3
  55. data/spec/support/fake_logger.rb +22 -21
  56. data/spec/support/fake_passenger.rb +4 -6
  57. data/spec/support/fake_unicorn.rb +2 -4
  58. data/spec/support/middleware_stack.rb +3 -3
  59. data/spec/support/writing_cache.rb +4 -4
  60. metadata +1 -1
@@ -12,8 +12,7 @@ describe 'CopyTunerClient' do
12
12
  config[:download_cache_dir] = download_cache_dir
13
13
  default_config = CopyTunerClient::Configuration.new.to_hash
14
14
  default_config[:s3_host] = 'copy-tuner.com'
15
- client = CopyTunerClient::Client.new(default_config.update(config))
16
- client
15
+ CopyTunerClient::Client.new(default_config.update(config))
17
16
  end
18
17
 
19
18
  def add_project
@@ -37,31 +36,31 @@ describe 'CopyTunerClient' do
37
36
 
38
37
  it '接続時のタイムアウトが設定されていること' do
39
38
  project = add_project
40
- client = build_client(:api_key => project.api_key, :http_open_timeout => 4)
41
- client.download { |ignore| }
39
+ client = build_client(api_key: project.api_key, http_open_timeout: 4)
40
+ client.download {}
42
41
  expect(http.open_timeout).to eq(4)
43
42
  end
44
43
 
45
44
  it '読み込み時のタイムアウトが設定されていること' do
46
45
  project = add_project
47
- client = build_client(:api_key => project.api_key, :http_read_timeout => 4)
48
- client.download { |ignore| }
46
+ client = build_client(api_key: project.api_key, http_read_timeout: 4)
47
+ client.download {}
49
48
  expect(http.read_timeout).to eq(4)
50
49
  end
51
50
 
52
51
  it 'secureがtrueの場合はSSL検証付きで接続すること' do
53
52
  project = add_project
54
- client = build_client(:api_key => project.api_key, :secure => true)
55
- client.download { |ignore| }
56
- expect(http.use_ssl?).to eq(true)
53
+ client = build_client(api_key: project.api_key, secure: true)
54
+ client.download {}
55
+ expect(http.use_ssl?).to be(true)
57
56
  expect(http.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
58
57
  end
59
58
 
60
59
  it 'secureがfalseの場合はSSLを使用しないこと' do
61
60
  project = add_project
62
- client = build_client(:api_key => project.api_key, :secure => false)
63
- client.download { |ignore| }
64
- expect(http.use_ssl?).to eq(false)
61
+ client = build_client(api_key: project.api_key, secure: false)
62
+ client.download {}
63
+ expect(http.use_ssl?).to be(false)
65
64
  end
66
65
 
67
66
  it 'HTTPエラーをConnectionErrorでラップすること' do
@@ -75,39 +74,39 @@ describe 'CopyTunerClient' do
75
74
  Net::ProtocolError.new,
76
75
  SocketError.new,
77
76
  OpenSSL::SSL::SSLError.new,
78
- Errno::ECONNREFUSED.new
77
+ Errno::ECONNREFUSED.new,
79
78
  ]
80
79
 
81
80
  errors.each do |original_error|
81
+ expected_message = "#{original_error.class.name}: #{original_error.message}"
82
82
  allow(http).to receive(:request).and_raise(original_error)
83
83
  client = build_client_with_project
84
- expect { client.download { |ignore| } }.
85
- to raise_error(CopyTunerClient::ConnectionError) { |error|
86
- expect(error.message).
87
- to eq("#{original_error.class.name}: #{original_error.message}")
84
+ expect { client.download {} }
85
+ .to raise_error(CopyTunerClient::ConnectionError) { |error|
86
+ expect(error.message).to eq(expected_message)
88
87
  }
89
88
  end
90
89
  end
91
90
 
92
91
  it 'ダウンロード時に500エラーが発生した場合はConnectionErrorになること' do
93
- client = build_client(:api_key => 'raise_error')
94
- expect { client.download { |ignore| } }.
95
- to raise_error(CopyTunerClient::ConnectionError)
92
+ client = build_client(api_key: 'raise_error')
93
+ expect { client.download {} }
94
+ .to raise_error(CopyTunerClient::ConnectionError)
96
95
  end
97
96
 
98
97
  it 'アップロード時に500エラーが発生した場合はConnectionErrorになること' do
99
- client = build_client(:api_key => 'raise_error')
98
+ client = build_client(api_key: 'raise_error')
100
99
  expect { client.upload({}) }.to raise_error(CopyTunerClient::ConnectionError)
101
100
  end
102
101
 
103
102
  it 'ダウンロード時に404エラーが発生した場合はInvalidApiKeyになること' do
104
- client = build_client(:api_key => 'bogus')
105
- expect { client.download { |ignore| } }.
106
- to raise_error(CopyTunerClient::InvalidApiKey)
103
+ client = build_client(api_key: 'bogus')
104
+ expect { client.download {} }
105
+ .to raise_error(CopyTunerClient::InvalidApiKey)
107
106
  end
108
107
 
109
108
  it 'アップロード時に404エラーが発生した場合はInvalidApiKeyになること' do
110
- client = build_client(:api_key => 'bogus')
109
+ client = build_client(api_key: 'bogus')
111
110
  expect { client.upload({}) }.to raise_error(CopyTunerClient::InvalidApiKey)
112
111
  end
113
112
  end
@@ -115,71 +114,71 @@ describe 'CopyTunerClient' do
115
114
  it '既存プロジェクトのpublishedなblurbをダウンロードできること' do
116
115
  project = add_project
117
116
  project.update({
118
- 'draft' => {
119
- 'key.one' => 'unexpected one',
120
- 'key.three' => 'unexpected three'
121
- },
122
- 'published' => {
123
- 'key.one' => 'expected one',
124
- 'key.two' => 'expected two'
125
- }
126
- })
127
- client = build_client(:api_key => project.api_key, :public => true)
117
+ 'draft' => {
118
+ 'key.one' => 'unexpected one',
119
+ 'key.three' => 'unexpected three',
120
+ },
121
+ 'published' => {
122
+ 'key.one' => 'expected one',
123
+ 'key.two' => 'expected two',
124
+ },
125
+ })
126
+ client = build_client(api_key: project.api_key, public: true)
128
127
  blurbs = nil
129
128
 
130
129
  client.download { |yielded| blurbs = yielded }
131
130
 
132
131
  expect(blurbs).to eq({
133
- 'key.one' => 'expected one',
134
- 'key.two' => 'expected two'
135
- })
132
+ 'key.one' => 'expected one',
133
+ 'key.two' => 'expected two',
134
+ })
136
135
  end
137
136
 
138
137
  it 'ダウンロードを実行したことをログに出力すること' do
139
138
  logger = FakeLogger.new
140
- client = build_client_with_project(:logger => logger)
141
- client.download { |ignore| }
139
+ client = build_client_with_project(logger:)
140
+ client.download {}
142
141
  expect(logger).to have_entry(:info, 'Downloaded translations')
143
142
  end
144
143
 
145
144
  it '既存プロジェクトのdraftなblurbをダウンロードできること' do
146
145
  project = add_project
147
146
  project.update({
148
- 'draft' => {
149
- 'key.one' => 'expected one',
150
- 'key.two' => 'expected two'
151
- },
152
- 'published' => {
153
- 'key.one' => 'unexpected one',
154
- 'key.three' => 'unexpected three'
155
- }
156
- })
157
- client = build_client(:api_key => project.api_key, :public => false)
147
+ 'draft' => {
148
+ 'key.one' => 'expected one',
149
+ 'key.two' => 'expected two',
150
+ },
151
+ 'published' => {
152
+ 'key.one' => 'unexpected one',
153
+ 'key.three' => 'unexpected three',
154
+ },
155
+ })
156
+ client = build_client(api_key: project.api_key, public: false)
158
157
  blurbs = nil
159
158
 
160
159
  client.download { |yielded| blurbs = yielded }
161
160
 
162
161
  expect(blurbs).to eq({
163
- 'key.one' => 'expected one',
164
- 'key.two' => 'expected two'
165
- })
162
+ 'key.one' => 'expected one',
163
+ 'key.two' => 'expected two',
164
+ })
166
165
  end
167
166
 
168
167
  it '304レスポンス時は2回目以降yieldされないこと' do
169
168
  project = add_project
170
- project.update('draft' => { 'key.one' => "expected one" })
169
+ project.update('draft' => { 'key.one' => 'expected one' })
171
170
  logger = FakeLogger.new
172
- client = build_client(:api_key => project.api_key,
173
- :public => false,
174
- :logger => logger)
171
+ client = build_client(api_key: project.api_key,
172
+ public: false,
173
+ logger:)
175
174
  yields = 0
176
175
 
177
176
  2.times do
178
- client.download { |ignore| yields += 1 }
177
+ client.download { |_ignore| yields += 1 }
179
178
  end
180
179
 
181
180
  expect(yields).to eq(1)
182
- expect(logger).to have_entry(:info, "No new translations")
181
+ expect(logger).to have_entry(:info, 'No new translations')
183
182
  end
184
183
 
185
184
  it '既存プロジェクトに存在しないblurbはアップロードされること' do
@@ -187,10 +186,10 @@ describe 'CopyTunerClient' do
187
186
 
188
187
  blurbs = {
189
188
  'key.one' => 'expected one',
190
- 'key.two' => 'expected two'
189
+ 'key.two' => 'expected two',
191
190
  }
192
191
 
193
- client = build_client(:api_key => project.api_key, :public => true)
192
+ client = build_client(api_key: project.api_key, public: true)
194
193
  client.upload(blurbs)
195
194
 
196
195
  expect(project.reload.draft).to eq(blurbs)
@@ -198,9 +197,9 @@ describe 'CopyTunerClient' do
198
197
 
199
198
  it 'アップロードを実行したことをログに出力すること' do
200
199
  logger = FakeLogger.new
201
- client = build_client_with_project(:logger => logger)
200
+ client = build_client_with_project(logger:)
202
201
  client.upload({})
203
- expect(logger).to have_entry(:info, "Uploaded missing translations")
202
+ expect(logger).to have_entry(:info, 'Uploaded missing translations')
204
203
  end
205
204
 
206
205
  it 'トップレベル定数からdeployできること' do
@@ -210,33 +209,35 @@ describe 'CopyTunerClient' do
210
209
  config.project_id = 1
211
210
  config.client = client
212
211
  end
213
- expect(client).to receive(:deploy)
212
+ allow(client).to receive(:deploy)
214
213
 
215
214
  CopyTunerClient.deploy
215
+
216
+ expect(client).to have_received(:deploy)
216
217
  end
217
218
 
218
219
  it 'deployが実行できること' do
219
220
  project = add_project
220
221
  project.update({
221
- 'draft' => {
222
- 'key.one' => "expected one",
223
- 'key.two' => "expected two"
224
- },
225
- 'published' => {
226
- 'key.one' => "unexpected one",
227
- 'key.two' => "unexpected one",
228
- }
229
- })
222
+ 'draft' => {
223
+ 'key.one' => 'expected one',
224
+ 'key.two' => 'expected two',
225
+ },
226
+ 'published' => {
227
+ 'key.one' => 'unexpected one',
228
+ 'key.two' => 'unexpected one',
229
+ },
230
+ })
230
231
  logger = FakeLogger.new
231
- client = build_client(:api_key => project.api_key, :logger => logger)
232
+ client = build_client(api_key: project.api_key, logger:)
232
233
 
233
234
  client.deploy
234
235
 
235
236
  expect(project.reload.published).to eq({
236
- 'key.one' => "expected one",
237
- 'key.two' => "expected two"
238
- })
239
- expect(logger).to have_entry(:info, "Deployed")
237
+ 'key.one' => 'expected one',
238
+ 'key.two' => 'expected two',
239
+ })
240
+ expect(logger).to have_entry(:info, 'Deployed')
240
241
  end
241
242
 
242
243
  it 'deploy時にエラーが発生した場合は例外が発生すること' do
@@ -256,14 +257,14 @@ describe 'CopyTunerClient' do
256
257
 
257
258
  it 'ダウンロード成功時にetagが更新されること' do
258
259
  project = add_project
259
- client = build_client(:api_key => project.api_key)
260
+ client = build_client(api_key: project.api_key)
260
261
 
261
262
  # モックでETagを設定
262
263
  response = Net::HTTPSuccess.new('1.1', '200', 'OK')
263
264
  allow(response).to receive(:body).and_return('{}')
264
265
  allow(response).to receive(:[]).with('ETag').and_return('"abc123"')
265
266
 
266
- http = double('http')
267
+ http = instance_double(Net::HTTP)
267
268
  allow(Net::HTTP).to receive(:new).and_return(http)
268
269
  allow(http).to receive(:open_timeout=)
269
270
  allow(http).to receive(:read_timeout=)
@@ -272,7 +273,7 @@ describe 'CopyTunerClient' do
272
273
  allow(http).to receive(:ca_file=)
273
274
  allow(http).to receive(:request).and_return(response)
274
275
 
275
- client.download { |blurbs| }
276
+ client.download {}
276
277
  expect(client.etag).to eq('"abc123"')
277
278
  end
278
279
  end