resizing 1.2.1 → 1.3.1
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 +4 -4
- data/.devcontainer/Dockerfile +73 -0
- data/.devcontainer/compose.yaml +58 -0
- data/.devcontainer/devcontainer-lock.json +9 -0
- data/.devcontainer/devcontainer.json +32 -0
- data/.devcontainer/post-create.sh +41 -0
- data/.github/copilot-instructions.md +1 -0
- data/.github/labeler.yml +28 -0
- data/.github/release.yml +35 -0
- data/.github/workflows/labeler.yml +20 -0
- data/.github/workflows/lint.yml +37 -0
- data/.github/workflows/test.yml +16 -9
- data/.gitignore +6 -0
- data/AGENTS.md +1 -0
- data/CHANGELOG.md +3 -0
- data/CLAUDE.md +68 -0
- data/Gemfile +9 -3
- data/README.md +114 -2
- data/Rakefile +5 -7
- data/bin/setup +3 -0
- data/git-hooks/pre-push +6 -0
- data/git-hooks/pre-push-ruby.sh +48 -0
- data/lib/resizing/carrier_wave/callback_file.rb +88 -0
- data/lib/resizing/carrier_wave/storage/file.rb +120 -47
- data/lib/resizing/carrier_wave/storage/remote.rb +7 -3
- data/lib/resizing/carrier_wave.rb +51 -7
- data/lib/resizing/client.rb +0 -1
- data/lib/resizing/configurable.rb +1 -1
- data/lib/resizing/configuration.rb +40 -10
- data/lib/resizing/mock_client.rb +23 -7
- data/lib/resizing/public_id.rb +3 -2
- data/lib/resizing/version.rb +1 -1
- data/lib/resizing.rb +0 -1
- data/resizing.gemspec +3 -3
- data/test/resizing/carrier_wave/storage/file_test.rb +455 -9
- data/test/resizing/carrier_wave/storage/remote_test.rb +91 -9
- data/test/resizing/carrier_wave_cache_callbacks_test.rb +224 -0
- data/test/resizing/carrier_wave_callback_file_test.rb +77 -0
- data/test/resizing/carrier_wave_test.rb +477 -23
- data/test/resizing/carrier_wave_uploader_test.rb +211 -0
- data/test/resizing/client_test.rb +324 -25
- data/test/resizing/configuration_test.rb +235 -10
- data/test/resizing/http_clientable_test.rb +27 -0
- data/test/resizing/mock_client_test.rb +111 -1
- data/test/resizing/public_id_test.rb +96 -0
- data/test/resizing_module_test.rb +110 -0
- data/test/resizing_test.rb +8 -0
- data/test/test_helper.rb +358 -11
- data/test/vcr/carrier_wave_test/update_image.yml +63 -0
- metadata +35 -10
data/test/test_helper.rb
CHANGED
|
@@ -5,6 +5,13 @@ require 'simplecov-cobertura'
|
|
|
5
5
|
|
|
6
6
|
SimpleCov.start do
|
|
7
7
|
add_filter '/test/'
|
|
8
|
+
# bundle install で vendor/ 配下に入る gem を計測対象から除外し、
|
|
9
|
+
# カバレッジ率が lib の実態を表すようにする
|
|
10
|
+
add_filter '/vendor/'
|
|
11
|
+
# version.rb is loaded by the gemspec before SimpleCov starts, so it always shows
|
|
12
|
+
# 0% coverage. Exclude it so that release PRs do not fail the patch check.
|
|
13
|
+
add_filter '/lib/resizing/version.rb'
|
|
14
|
+
track_files 'lib/**/*.rb'
|
|
8
15
|
|
|
9
16
|
if ENV['CI']
|
|
10
17
|
formatter SimpleCov::Formatter::CoberturaFormatter
|
|
@@ -20,6 +27,8 @@ SimpleCov.start do
|
|
|
20
27
|
end
|
|
21
28
|
|
|
22
29
|
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
|
30
|
+
require 'digest'
|
|
31
|
+
require 'socket'
|
|
23
32
|
require 'time'
|
|
24
33
|
require 'timecop'
|
|
25
34
|
require 'vcr'
|
|
@@ -47,6 +56,40 @@ VCR.configure do |c|
|
|
|
47
56
|
end
|
|
48
57
|
end
|
|
49
58
|
|
|
59
|
+
# Resizing::Client の代わりに使う偽クライアント (delete の応答を固定し、呼び出しを記録する)
|
|
60
|
+
class FakeApiClient
|
|
61
|
+
attr_reader :deleted_ids
|
|
62
|
+
|
|
63
|
+
def initialize(response)
|
|
64
|
+
@response = response
|
|
65
|
+
@deleted_ids = []
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def delete(image_id)
|
|
69
|
+
@deleted_ids << image_id
|
|
70
|
+
@response.dup
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Resizing::Client を FakeApiClient に差し替えるヘルパー
|
|
75
|
+
module FakeApiClientAssertions
|
|
76
|
+
# Resizing::Client.new が FakeApiClient を返す状態でブロックを実行する
|
|
77
|
+
#
|
|
78
|
+
# @param response [Hash] 偽クライアントの delete が返す固定レスポンス
|
|
79
|
+
# @yield [FakeApiClient] 差し替えた偽クライアント
|
|
80
|
+
# @return [Object] ブロックの戻り値
|
|
81
|
+
#
|
|
82
|
+
# @example
|
|
83
|
+
# with_fake_api_client({ 'id' => IMAGE_ID }) do |fake|
|
|
84
|
+
# file.delete
|
|
85
|
+
# assert_equal [IMAGE_ID], fake.deleted_ids
|
|
86
|
+
# end
|
|
87
|
+
def with_fake_api_client(response)
|
|
88
|
+
fake = FakeApiClient.new(response)
|
|
89
|
+
Resizing::Client.stub(:new, fake) { yield fake }
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
50
93
|
# VCRカセットのリクエストが実際に使用されたかを検証するヘルパー
|
|
51
94
|
module VCRRequestAssertions
|
|
52
95
|
# VCRカセット内でブロックを実行し、カセットのインタラクションがすべて使用されたことを確認
|
|
@@ -61,7 +104,7 @@ module VCRRequestAssertions
|
|
|
61
104
|
# model.remove_resizing_picture!
|
|
62
105
|
# model.save!
|
|
63
106
|
# end
|
|
64
|
-
def assert_vcr_requests_made(cassette_name, options = {}
|
|
107
|
+
def assert_vcr_requests_made(cassette_name, options = {})
|
|
65
108
|
options = { record: :none }.merge(options)
|
|
66
109
|
|
|
67
110
|
VCR.use_cassette(cassette_name, options) do |cassette|
|
|
@@ -94,7 +137,7 @@ module VCRRequestAssertions
|
|
|
94
137
|
# assert_vcr_requests_count 'client/post', 1 do
|
|
95
138
|
# Resizing.post(file)
|
|
96
139
|
# end
|
|
97
|
-
def assert_vcr_requests_count(cassette_name, expected_count, options = {}
|
|
140
|
+
def assert_vcr_requests_count(cassette_name, expected_count, options = {})
|
|
98
141
|
options = { record: :none }.merge(options)
|
|
99
142
|
|
|
100
143
|
VCR.use_cassette(cassette_name, options) do |cassette|
|
|
@@ -129,15 +172,172 @@ module VCRRequestAssertions
|
|
|
129
172
|
end
|
|
130
173
|
end
|
|
131
174
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
175
|
+
# 全テストで共通の Resizing の設定と、アップロードのテスト用ヘルパー
|
|
176
|
+
#
|
|
177
|
+
# 設定値と識別子は test/vcr/ のカセットに記録されているホスト・プロジェクト・
|
|
178
|
+
# レスポンスと揃えてあるので、変更するときはカセットも合わせて録り直すこと
|
|
179
|
+
module ResizingTestConfiguration
|
|
180
|
+
CONFIGURATION_TEMPLATE = {
|
|
181
|
+
image_host: 'http://192.168.56.101:5000',
|
|
182
|
+
project_id: 'e06e710d-f026-4dcf-b2c0-eab0de8bb83f',
|
|
183
|
+
secret_token: 'ewbym2r1pk49x1d2lxdbiiavnqp25j2kh00hsg3koy0ppm620x5mhlmgl3rq5ci8',
|
|
184
|
+
open_timeout: 10,
|
|
185
|
+
response_timeout: 20
|
|
186
|
+
}.freeze
|
|
187
|
+
|
|
188
|
+
# carrier_wave_test/save カセットが返す画像の public id
|
|
189
|
+
UPLOADED_IDENTIFIER = '/projects/e06e710d-f026-4dcf-b2c0-eab0de8bb83f/upload/images/' \
|
|
190
|
+
'14ea7aac-a194-4330-931f-6b562aec413d/v_8c5lEhDB5RT3PZp1Fn5PYGm9YVx_x0e'
|
|
191
|
+
|
|
192
|
+
def configuration_template
|
|
193
|
+
CONFIGURATION_TEMPLATE
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# @param overrides [Hash] 既定の設定を上書きする値
|
|
197
|
+
def configure_resizing(overrides = {})
|
|
198
|
+
Resizing.configure = CONFIGURATION_TEMPLATE.merge(overrides)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def expect_identifier
|
|
202
|
+
UPLOADED_IDENTIFIER
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def expect_url
|
|
206
|
+
"#{CONFIGURATION_TEMPLATE[:image_host]}#{UPLOADED_IDENTIFIER}"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# アップロード用のサンプル画像
|
|
210
|
+
# 実際に POST が発行されるので VCR カセット内で使うこと
|
|
211
|
+
def sample_uploaded_file
|
|
212
|
+
file = File.open('test/data/images/sample1.jpg', 'r')
|
|
213
|
+
ActionDispatch::Http::UploadedFile.new(
|
|
214
|
+
filename: File.basename(file.path),
|
|
215
|
+
type: 'image/jpeg',
|
|
216
|
+
tempfile: file
|
|
217
|
+
)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# モデルにサンプル画像を添付するヘルパーメソッド
|
|
221
|
+
# VCRカセット内で呼び出す必要がある
|
|
222
|
+
def attach_sample_image(model)
|
|
223
|
+
model.resizing_picture = sample_uploaded_file
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# `remote_<column>_url=` でダウンロードされたのと同じ形のファイル
|
|
227
|
+
# (CarrierWave::Downloader::RemoteFile) を、HTTP を発行せずに組み立てる
|
|
228
|
+
#
|
|
229
|
+
# @param url [String] ダウンロード元 URL (ファイル名の決定に使われる)
|
|
230
|
+
# @param content_type [String] レスポンスの Content-Type
|
|
231
|
+
# @param body [String] レスポンスボディ (既定はサンプル画像)
|
|
232
|
+
def sample_remote_file(url, content_type:, body: File.binread('test/data/images/sample1.jpg'))
|
|
233
|
+
response = Net::HTTPOK.new('1.1', '200', 'OK')
|
|
234
|
+
response['Content-Type'] = content_type
|
|
235
|
+
response.instance_variable_set(:@body, body)
|
|
236
|
+
response.instance_variable_set(:@read, true)
|
|
237
|
+
response.uri = URI.parse(url)
|
|
238
|
+
::CarrierWave::Downloader::RemoteFile.new(response)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# `remote_<column>_url=` のダウンロードを差し替えて、与えた RemoteFile を返すようにする
|
|
242
|
+
# (テストからは外部 HTTP を発行しないため)
|
|
243
|
+
#
|
|
244
|
+
# @param remote_file [CarrierWave::Downloader::RemoteFile] ダウンロード結果として返すファイル
|
|
245
|
+
def with_stubbed_download(remote_file, &block)
|
|
246
|
+
downloader = Object.new
|
|
247
|
+
downloader.define_singleton_method(:download) { |_url, _headers = {}| remote_file }
|
|
248
|
+
::CarrierWave::Downloader::Base.stub(:new, downloader, &block)
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Test database setup
|
|
253
|
+
#
|
|
254
|
+
# By default each test process creates its own database and drops it when the
|
|
255
|
+
# run finishes, so that several test processes sharing one MySQL server do not
|
|
256
|
+
# overwrite each other's tables and records.
|
|
257
|
+
#
|
|
258
|
+
# The server can be overridden with MYSQL_HOST / MYSQL_PORT / MYSQL_USER /
|
|
259
|
+
# MYSQL_PASSWORD (the dev container runs MySQL in a separate container).
|
|
260
|
+
# Setting MYSQL_DATABASE uses that database as is and never drops it; give each
|
|
261
|
+
# concurrent process a different name in that case.
|
|
262
|
+
module TestDatabase
|
|
263
|
+
BASE_NAME = 'resizing_gem_test'
|
|
264
|
+
|
|
265
|
+
module_function
|
|
266
|
+
|
|
267
|
+
# Host identifier mixed into the per-process database name, so that PIDs from
|
|
268
|
+
# different hosts do not collide on a shared MySQL server
|
|
269
|
+
def host_token
|
|
270
|
+
@host_token ||= Digest::MD5.hexdigest(Socket.gethostname)[0, 8]
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def per_process_name_pattern
|
|
274
|
+
/\A#{Regexp.escape(BASE_NAME)}_#{host_token}_(\d+)\z/
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def database_name
|
|
278
|
+
@database_name ||= ENV['MYSQL_DATABASE'] || "#{BASE_NAME}_#{host_token}_#{Process.pid}"
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Whether the database belongs to this process alone and can be dropped
|
|
282
|
+
def ephemeral?
|
|
283
|
+
ENV['MYSQL_DATABASE'].nil?
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def server_config
|
|
287
|
+
{
|
|
288
|
+
adapter: 'mysql2',
|
|
289
|
+
host: ENV.fetch('MYSQL_HOST', '127.0.0.1'),
|
|
290
|
+
port: Integer(ENV.fetch('MYSQL_PORT', '3306')),
|
|
291
|
+
encoding: 'utf8',
|
|
292
|
+
username: ENV.fetch('MYSQL_USER', 'root'),
|
|
293
|
+
password: ENV.fetch('MYSQL_PASSWORD', 'secret')
|
|
294
|
+
}
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def setup
|
|
298
|
+
ActiveRecord::Base.establish_connection(server_config)
|
|
299
|
+
drop_abandoned_databases if ephemeral?
|
|
300
|
+
ActiveRecord::Base.connection.execute("create database if not exists `#{database_name}`")
|
|
301
|
+
ActiveRecord::Base.establish_connection(server_config.merge(database: database_name))
|
|
302
|
+
|
|
303
|
+
# Minitest.after_run, not at_exit: at_exit handlers run in reverse order of
|
|
304
|
+
# registration, so this one would drop the database before the tests run
|
|
305
|
+
Minitest.after_run { drop_database } if ephemeral?
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def drop_database
|
|
309
|
+
ActiveRecord::Base.establish_connection(server_config)
|
|
310
|
+
ActiveRecord::Base.connection.execute("drop database if exists `#{database_name}`")
|
|
311
|
+
rescue StandardError => e
|
|
312
|
+
warn "failed to drop test database #{database_name}: #{e.message}"
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# Clean up databases left behind by processes that were killed before they
|
|
316
|
+
# could drop their own
|
|
317
|
+
def drop_abandoned_databases
|
|
318
|
+
connection = ActiveRecord::Base.connection
|
|
319
|
+
|
|
320
|
+
connection.select_values('show databases').each do |database|
|
|
321
|
+
matched = per_process_name_pattern.match(database)
|
|
322
|
+
next if matched.nil? || process_alive?(matched[1].to_i)
|
|
323
|
+
|
|
324
|
+
connection.execute("drop database if exists `#{database}`")
|
|
325
|
+
end
|
|
326
|
+
rescue StandardError => e
|
|
327
|
+
warn "failed to drop abandoned test databases: #{e.message}"
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def process_alive?(pid)
|
|
331
|
+
Process.kill(0, pid)
|
|
332
|
+
true
|
|
333
|
+
rescue Errno::ESRCH
|
|
334
|
+
false
|
|
335
|
+
rescue Errno::EPERM
|
|
336
|
+
true
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
TestDatabase.setup
|
|
141
341
|
|
|
142
342
|
ActiveRecord::Schema.define do
|
|
143
343
|
self.verbose = false
|
|
@@ -186,10 +386,98 @@ class ResizingUploaderWithDefaultURL < CarrierWave::Uploader::Base
|
|
|
186
386
|
end
|
|
187
387
|
end
|
|
188
388
|
|
|
389
|
+
# before :cache コールバック (拡張子 / content_type / サイズのチェック) のテスト用アップローダ
|
|
390
|
+
class ResizingUploaderWithExtensionAllowlist < CarrierWave::Uploader::Base
|
|
391
|
+
include Resizing::CarrierWave
|
|
392
|
+
|
|
393
|
+
def extension_allowlist
|
|
394
|
+
%w[png]
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
class ResizingUploaderWithExtensionDenylist < CarrierWave::Uploader::Base
|
|
399
|
+
include Resizing::CarrierWave
|
|
400
|
+
|
|
401
|
+
def extension_denylist
|
|
402
|
+
%w[jpg]
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# 拡張子の判定が content_type から行われることのテスト用アップローダ
|
|
407
|
+
# (sample1.jpg / image/jpeg を受け付け、image/png は拒否する)
|
|
408
|
+
class ResizingUploaderWithJpegAllowlist < CarrierWave::Uploader::Base
|
|
409
|
+
include Resizing::CarrierWave
|
|
410
|
+
|
|
411
|
+
def extension_allowlist
|
|
412
|
+
%w[jpg jpeg]
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
class ResizingUploaderWithContentTypeAllowlist < CarrierWave::Uploader::Base
|
|
417
|
+
include Resizing::CarrierWave
|
|
418
|
+
|
|
419
|
+
def content_type_allowlist
|
|
420
|
+
['image/png']
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
class ResizingUploaderWithSizeRange < CarrierWave::Uploader::Base
|
|
425
|
+
include Resizing::CarrierWave
|
|
426
|
+
|
|
427
|
+
def size_range
|
|
428
|
+
0..10
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
# process! が発火しないことのテスト用アップローダ
|
|
433
|
+
# convert / transformation は配信 URL の transform を組み立てるための宣言であり
|
|
434
|
+
# uploader のメソッドとしては存在しないので、process! が走ると NoMethodError になる
|
|
435
|
+
class ResizingUploaderWithUndefinedProcessor < CarrierWave::Uploader::Base
|
|
436
|
+
include Resizing::CarrierWave
|
|
437
|
+
|
|
438
|
+
process convert: 'png'
|
|
439
|
+
end
|
|
440
|
+
|
|
189
441
|
class TestModel < ::ActiveRecord::Base
|
|
190
442
|
mount_uploader :resizing_picture, ResizingUploader
|
|
191
443
|
end
|
|
192
444
|
|
|
445
|
+
class TestModelWithExtensionAllowlist < ::ActiveRecord::Base
|
|
446
|
+
self.table_name = 'test_models'
|
|
447
|
+
|
|
448
|
+
mount_uploader :resizing_picture, ResizingUploaderWithExtensionAllowlist
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
class TestModelWithExtensionDenylist < ::ActiveRecord::Base
|
|
452
|
+
self.table_name = 'test_models'
|
|
453
|
+
|
|
454
|
+
mount_uploader :resizing_picture, ResizingUploaderWithExtensionDenylist
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
class TestModelWithJpegAllowlist < ::ActiveRecord::Base
|
|
458
|
+
self.table_name = 'test_models'
|
|
459
|
+
|
|
460
|
+
mount_uploader :resizing_picture, ResizingUploaderWithJpegAllowlist
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
class TestModelWithContentTypeAllowlist < ::ActiveRecord::Base
|
|
464
|
+
self.table_name = 'test_models'
|
|
465
|
+
|
|
466
|
+
mount_uploader :resizing_picture, ResizingUploaderWithContentTypeAllowlist
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
class TestModelWithSizeRange < ::ActiveRecord::Base
|
|
470
|
+
self.table_name = 'test_models'
|
|
471
|
+
|
|
472
|
+
mount_uploader :resizing_picture, ResizingUploaderWithSizeRange
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
class TestModelWithUndefinedProcessor < ::ActiveRecord::Base
|
|
476
|
+
self.table_name = 'test_models'
|
|
477
|
+
|
|
478
|
+
mount_uploader :resizing_picture, ResizingUploaderWithUndefinedProcessor
|
|
479
|
+
end
|
|
480
|
+
|
|
193
481
|
class TestJPGModel < ::ActiveRecord::Base
|
|
194
482
|
mount_uploader :resizing_picture, ResizingJPGUploader
|
|
195
483
|
end
|
|
@@ -197,3 +485,62 @@ end
|
|
|
197
485
|
class TestModelWithDefaultURL < ::ActiveRecord::Base
|
|
198
486
|
mount_uploader :resizing_picture, ResizingUploaderWithDefaultURL
|
|
199
487
|
end
|
|
488
|
+
|
|
489
|
+
# コールバックのテスト用モデル
|
|
490
|
+
# mount_uploader が登録する各種コールバックが正しく動作するかをテストするため
|
|
491
|
+
# カスタムコールバックを追加して呼び出しを追跡する
|
|
492
|
+
class TestModelWithCallbackTracking < ::ActiveRecord::Base
|
|
493
|
+
self.table_name = 'test_models'
|
|
494
|
+
|
|
495
|
+
mount_uploader :resizing_picture, ResizingUploader
|
|
496
|
+
|
|
497
|
+
attr_accessor :callback_log
|
|
498
|
+
|
|
499
|
+
# before_save / after_save コールバック
|
|
500
|
+
before_save :track_before_save
|
|
501
|
+
after_save :track_after_save
|
|
502
|
+
|
|
503
|
+
# before_destroy / after_destroy コールバック
|
|
504
|
+
before_destroy :track_before_destroy
|
|
505
|
+
after_destroy :track_after_destroy
|
|
506
|
+
|
|
507
|
+
# after_commit コールバック
|
|
508
|
+
after_commit :track_create_commit, on: :create
|
|
509
|
+
after_commit :track_update_commit, on: :update
|
|
510
|
+
after_commit :track_destroy_commit, on: :destroy
|
|
511
|
+
|
|
512
|
+
def initialize(*args)
|
|
513
|
+
super
|
|
514
|
+
@callback_log = []
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
private
|
|
518
|
+
|
|
519
|
+
def track_before_save
|
|
520
|
+
@callback_log << :before_save
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
def track_after_save
|
|
524
|
+
@callback_log << :after_save
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
def track_before_destroy
|
|
528
|
+
@callback_log << :before_destroy
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
def track_after_destroy
|
|
532
|
+
@callback_log << :after_destroy
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
def track_create_commit
|
|
536
|
+
@callback_log << :create_commit
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
def track_update_commit
|
|
540
|
+
@callback_log << :update_commit
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
def track_destroy_commit
|
|
544
|
+
@callback_log << :destroy_commit
|
|
545
|
+
end
|
|
546
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
http_interactions:
|
|
3
|
+
- request:
|
|
4
|
+
method: post
|
|
5
|
+
uri: http://192.168.56.101:5000/projects/e06e710d-f026-4dcf-b2c0-eab0de8bb83f/upload/images/
|
|
6
|
+
body:
|
|
7
|
+
encoding: ASCII-8BIT
|
|
8
|
+
string: ''
|
|
9
|
+
headers:
|
|
10
|
+
User-Agent:
|
|
11
|
+
- Faraday v1.0.1
|
|
12
|
+
response:
|
|
13
|
+
status:
|
|
14
|
+
code: 200
|
|
15
|
+
message: OK
|
|
16
|
+
headers:
|
|
17
|
+
content-type:
|
|
18
|
+
- application/json; charset=utf-8
|
|
19
|
+
body:
|
|
20
|
+
encoding: UTF-8
|
|
21
|
+
string: '{"id":"old-image-id-1111-1111-111111111111","project_id":"e06e710d-f026-4dcf-b2c0-eab0de8bb83f","content_type":"image/jpeg","version":"v1","public_id":"/projects/e06e710d-f026-4dcf-b2c0-eab0de8bb83f/upload/images/old-image-id-1111-1111-111111111111/v1"}'
|
|
22
|
+
recorded_at: Sun, 11 Oct 2020 04:56:48 GMT
|
|
23
|
+
- request:
|
|
24
|
+
method: post
|
|
25
|
+
uri: http://192.168.56.101:5000/projects/e06e710d-f026-4dcf-b2c0-eab0de8bb83f/upload/images/
|
|
26
|
+
body:
|
|
27
|
+
encoding: ASCII-8BIT
|
|
28
|
+
string: ''
|
|
29
|
+
headers:
|
|
30
|
+
User-Agent:
|
|
31
|
+
- Faraday v1.0.1
|
|
32
|
+
response:
|
|
33
|
+
status:
|
|
34
|
+
code: 200
|
|
35
|
+
message: OK
|
|
36
|
+
headers:
|
|
37
|
+
content-type:
|
|
38
|
+
- application/json; charset=utf-8
|
|
39
|
+
body:
|
|
40
|
+
encoding: UTF-8
|
|
41
|
+
string: '{"id":"new-image-id-2222-2222-222222222222","project_id":"e06e710d-f026-4dcf-b2c0-eab0de8bb83f","content_type":"image/jpeg","version":"v2","public_id":"/projects/e06e710d-f026-4dcf-b2c0-eab0de8bb83f/upload/images/new-image-id-2222-2222-222222222222/v2"}'
|
|
42
|
+
recorded_at: Sun, 11 Oct 2020 04:56:49 GMT
|
|
43
|
+
- request:
|
|
44
|
+
method: delete
|
|
45
|
+
uri: http://192.168.56.101:5000/projects/e06e710d-f026-4dcf-b2c0-eab0de8bb83f/upload/images/old-image-id-1111-1111-111111111111
|
|
46
|
+
body:
|
|
47
|
+
encoding: US-ASCII
|
|
48
|
+
string: ''
|
|
49
|
+
headers:
|
|
50
|
+
User-Agent:
|
|
51
|
+
- Faraday v1.0.1
|
|
52
|
+
response:
|
|
53
|
+
status:
|
|
54
|
+
code: 200
|
|
55
|
+
message: OK
|
|
56
|
+
headers:
|
|
57
|
+
content-type:
|
|
58
|
+
- application/json; charset=utf-8
|
|
59
|
+
body:
|
|
60
|
+
encoding: UTF-8
|
|
61
|
+
string: '{"id":"old-image-id-1111-1111-111111111111","project_id":"e06e710d-f026-4dcf-b2c0-eab0de8bb83f"}'
|
|
62
|
+
recorded_at: Sun, 11 Oct 2020 04:56:50 GMT
|
|
63
|
+
recorded_with: VCR 6.0.0
|
metadata
CHANGED
|
@@ -1,43 +1,49 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: resizing
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Junichiro Kasuya
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-09-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '1.0'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '3'
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
24
|
-
- - "
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '1.0'
|
|
30
|
+
- - "<"
|
|
25
31
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
32
|
+
version: '3'
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: faraday-multipart
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
|
30
36
|
requirements:
|
|
31
37
|
- - ">="
|
|
32
38
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
39
|
+
version: '1.0'
|
|
34
40
|
type: :runtime
|
|
35
41
|
prerelease: false
|
|
36
42
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
43
|
requirements:
|
|
38
44
|
- - ">="
|
|
39
45
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
46
|
+
version: '1.0'
|
|
41
47
|
- !ruby/object:Gem::Dependency
|
|
42
48
|
name: carrierwave
|
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -185,10 +191,22 @@ executables: []
|
|
|
185
191
|
extensions: []
|
|
186
192
|
extra_rdoc_files: []
|
|
187
193
|
files:
|
|
194
|
+
- ".devcontainer/Dockerfile"
|
|
195
|
+
- ".devcontainer/compose.yaml"
|
|
196
|
+
- ".devcontainer/devcontainer-lock.json"
|
|
197
|
+
- ".devcontainer/devcontainer.json"
|
|
198
|
+
- ".devcontainer/post-create.sh"
|
|
199
|
+
- ".github/copilot-instructions.md"
|
|
200
|
+
- ".github/labeler.yml"
|
|
201
|
+
- ".github/release.yml"
|
|
202
|
+
- ".github/workflows/labeler.yml"
|
|
203
|
+
- ".github/workflows/lint.yml"
|
|
188
204
|
- ".github/workflows/test.yml"
|
|
189
205
|
- ".gitignore"
|
|
190
206
|
- ".rubocop.yml"
|
|
207
|
+
- AGENTS.md
|
|
191
208
|
- CHANGELOG.md
|
|
209
|
+
- CLAUDE.md
|
|
192
210
|
- Gemfile
|
|
193
211
|
- LICENSE.txt
|
|
194
212
|
- README.md
|
|
@@ -197,11 +215,14 @@ files:
|
|
|
197
215
|
- bin/generate-changelog
|
|
198
216
|
- bin/setup
|
|
199
217
|
- docker-compose.yml
|
|
218
|
+
- git-hooks/pre-push
|
|
219
|
+
- git-hooks/pre-push-ruby.sh
|
|
200
220
|
- lib/resizing.rb
|
|
201
221
|
- lib/resizing/active_storage.rb
|
|
202
222
|
- lib/resizing/active_storage/service.rb
|
|
203
223
|
- lib/resizing/active_storage/service/resizing_service.rb
|
|
204
224
|
- lib/resizing/carrier_wave.rb
|
|
225
|
+
- lib/resizing/carrier_wave/callback_file.rb
|
|
205
226
|
- lib/resizing/carrier_wave/storage/file.rb
|
|
206
227
|
- lib/resizing/carrier_wave/storage/remote.rb
|
|
207
228
|
- lib/resizing/client.rb
|
|
@@ -218,7 +239,10 @@ files:
|
|
|
218
239
|
- test/resizing/active_storage_service_test.rb
|
|
219
240
|
- test/resizing/carrier_wave/storage/file_test.rb
|
|
220
241
|
- test/resizing/carrier_wave/storage/remote_test.rb
|
|
242
|
+
- test/resizing/carrier_wave_cache_callbacks_test.rb
|
|
243
|
+
- test/resizing/carrier_wave_callback_file_test.rb
|
|
221
244
|
- test/resizing/carrier_wave_test.rb
|
|
245
|
+
- test/resizing/carrier_wave_uploader_test.rb
|
|
222
246
|
- test/resizing/client_test.rb
|
|
223
247
|
- test/resizing/configurable_test.rb
|
|
224
248
|
- test/resizing/configuration_test.rb
|
|
@@ -232,6 +256,7 @@ files:
|
|
|
232
256
|
- test/test_helper.rb
|
|
233
257
|
- test/vcr/carrier_wave_test/remove_resizing_picture.yml
|
|
234
258
|
- test/vcr/carrier_wave_test/save.yml
|
|
259
|
+
- test/vcr/carrier_wave_test/update_image.yml
|
|
235
260
|
- test/vcr/client/delete.yml
|
|
236
261
|
- test/vcr/client/error.yml
|
|
237
262
|
- test/vcr/client/metadata.yml
|
|
@@ -252,14 +277,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
252
277
|
requirements:
|
|
253
278
|
- - ">="
|
|
254
279
|
- !ruby/object:Gem::Version
|
|
255
|
-
version: 3.
|
|
280
|
+
version: 3.1.0
|
|
256
281
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
257
282
|
requirements:
|
|
258
283
|
- - ">="
|
|
259
284
|
- !ruby/object:Gem::Version
|
|
260
285
|
version: '0'
|
|
261
286
|
requirements: []
|
|
262
|
-
rubygems_version: 3.
|
|
287
|
+
rubygems_version: 3.3.27
|
|
263
288
|
signing_key:
|
|
264
289
|
specification_version: 4
|
|
265
290
|
summary: Client and utilities for Resizing
|