resizing 1.2.2 → 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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +73 -0
  3. data/.devcontainer/compose.yaml +58 -0
  4. data/.devcontainer/devcontainer-lock.json +9 -0
  5. data/.devcontainer/devcontainer.json +32 -0
  6. data/.devcontainer/post-create.sh +41 -0
  7. data/.github/copilot-instructions.md +1 -0
  8. data/.github/labeler.yml +28 -0
  9. data/.github/release.yml +35 -0
  10. data/.github/workflows/labeler.yml +20 -0
  11. data/.github/workflows/lint.yml +37 -0
  12. data/.github/workflows/test.yml +16 -9
  13. data/AGENTS.md +1 -0
  14. data/CHANGELOG.md +3 -0
  15. data/CLAUDE.md +68 -0
  16. data/Gemfile +9 -3
  17. data/README.md +114 -2
  18. data/Rakefile +5 -7
  19. data/bin/setup +3 -0
  20. data/git-hooks/pre-push +6 -0
  21. data/git-hooks/pre-push-ruby.sh +48 -0
  22. data/lib/resizing/carrier_wave/callback_file.rb +88 -0
  23. data/lib/resizing/carrier_wave/storage/file.rb +84 -36
  24. data/lib/resizing/carrier_wave/storage/remote.rb +7 -3
  25. data/lib/resizing/carrier_wave.rb +41 -6
  26. data/lib/resizing/client.rb +0 -1
  27. data/lib/resizing/configurable.rb +1 -1
  28. data/lib/resizing/configuration.rb +40 -10
  29. data/lib/resizing/mock_client.rb +23 -7
  30. data/lib/resizing/public_id.rb +3 -2
  31. data/lib/resizing/version.rb +1 -1
  32. data/lib/resizing.rb +0 -1
  33. data/resizing.gemspec +3 -3
  34. data/test/resizing/carrier_wave/storage/file_test.rb +455 -9
  35. data/test/resizing/carrier_wave/storage/remote_test.rb +91 -9
  36. data/test/resizing/carrier_wave_cache_callbacks_test.rb +224 -0
  37. data/test/resizing/carrier_wave_callback_file_test.rb +77 -0
  38. data/test/resizing/carrier_wave_test.rb +201 -26
  39. data/test/resizing/carrier_wave_uploader_test.rb +211 -0
  40. data/test/resizing/client_test.rb +324 -25
  41. data/test/resizing/configuration_test.rb +235 -10
  42. data/test/resizing/http_clientable_test.rb +27 -0
  43. data/test/resizing/mock_client_test.rb +111 -1
  44. data/test/resizing/public_id_test.rb +96 -0
  45. data/test/resizing_module_test.rb +110 -0
  46. data/test/resizing_test.rb +8 -0
  47. data/test/test_helper.rb +297 -9
  48. metadata +33 -9
@@ -0,0 +1,224 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Resizing
6
+ # Resizing::CarrierWave#cache! が CarrierWave の :cache コールバックを通すことをテストする
7
+ #
8
+ # - before :cache のチェック (拡張子 / content_type / サイズ) はアップロード前に働く
9
+ # - process! と cache_versions! は Resizing の設計に合わないので発火しない
10
+ class CarrierWaveCacheCallbacksTest < Minitest::Test
11
+ include VCRRequestAssertions
12
+ include ResizingTestConfiguration
13
+
14
+ def setup
15
+ TestModel.delete_all
16
+ configure_resizing
17
+ end
18
+
19
+ def teardown; end
20
+
21
+ # ============================================================
22
+ # before :cache のチェックが働くこと (アップロードされない)
23
+ # ============================================================
24
+
25
+ def test_extension_allowlist_rejects_file_without_uploading
26
+ assert_rejected_before_upload TestModelWithExtensionAllowlist
27
+ end
28
+
29
+ def test_extension_denylist_rejects_file_without_uploading
30
+ assert_rejected_before_upload TestModelWithExtensionDenylist
31
+ end
32
+
33
+ def test_content_type_allowlist_rejects_file_without_uploading
34
+ assert_rejected_before_upload TestModelWithContentTypeAllowlist
35
+ end
36
+
37
+ def test_size_range_rejects_file_without_uploading
38
+ assert_rejected_before_upload TestModelWithSizeRange
39
+ end
40
+
41
+ def test_cache_raises_integrity_error_when_called_directly
42
+ model = TestModelWithExtensionAllowlist.new
43
+ uploader = ResizingUploaderWithExtensionAllowlist.new(model, :resizing_picture)
44
+
45
+ assert_vcr_no_requests 'carrier_wave_test/save' do
46
+ assert_raises(::CarrierWave::IntegrityError) { uploader.cache!(sample_uploaded_file) }
47
+ end
48
+
49
+ assert_nil model.read_attribute(:resizing_picture)
50
+ end
51
+
52
+ def test_cache_ignores_empty_file
53
+ # 中身のないファイルは CarrierWave 本体の cache! と同じくアップロードしない
54
+ model = TestModel.new
55
+ uploader = ResizingUploader.new(model, :resizing_picture)
56
+
57
+ assert_vcr_no_requests 'carrier_wave_test/save' do
58
+ assert_nil uploader.cache!(StringIO.new(''))
59
+ end
60
+
61
+ assert_nil model.read_attribute(:resizing_picture)
62
+ end
63
+
64
+ # ============================================================
65
+ # 拡張子のチェックが content_type から判定されること
66
+ # ============================================================
67
+
68
+ # Resizing の公開 URL は末尾がバージョン文字列 (`/v<version>`) で、ドットを含むため
69
+ # ファイル名から取れる「拡張子」はバージョンの一部 (`Fv_Q`) になる
70
+ # (ダウンロードは差し替えるので、URL の中身は実在しなくてよい)
71
+ RESIZING_IMAGE_URL = "#{ResizingTestConfiguration::CONFIGURATION_TEMPLATE[:image_host]}" \
72
+ "/projects/#{ResizingTestConfiguration::CONFIGURATION_TEMPLATE[:project_id]}" \
73
+ '/upload/images/3f2c9d1e-5b7a-4e8c-9a0d-6c1b2e3f4a5d/v0cRq7Yb2mZt9LxA3wN8eKd5pHs1.Fv_Q'.freeze
74
+
75
+ def test_remote_resizing_url_is_accepted_by_content_type
76
+ # `remote_<column>_url=` に Resizing の URL を渡した場合、ファイル名の拡張子 (Fv_Q) ではなく
77
+ # レスポンスの Content-Type (image/jpeg) で判定され、アップロードされる
78
+ model = TestModelWithJpegAllowlist.new
79
+ remote_file = sample_remote_file(RESIZING_IMAGE_URL, content_type: 'image/jpeg')
80
+
81
+ assert_vcr_requests_count 'carrier_wave_test/save', 1 do
82
+ with_stubbed_download(remote_file) do
83
+ model.remote_resizing_picture_url = RESIZING_IMAGE_URL
84
+ end
85
+ end
86
+
87
+ assert model.valid?, model.errors.full_messages.join(', ')
88
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
89
+ end
90
+
91
+ def test_remote_file_is_rejected_when_content_type_is_not_allowed
92
+ # Content-Type が image/png なら、拡張子の許可リスト (jpg / jpeg) に合わないので拒否される
93
+ model = TestModelWithJpegAllowlist.new
94
+ remote_file = sample_remote_file(RESIZING_IMAGE_URL, content_type: 'image/png')
95
+
96
+ assert_vcr_no_requests 'carrier_wave_test/save' do
97
+ with_stubbed_download(remote_file) do
98
+ model.remote_resizing_picture_url = RESIZING_IMAGE_URL
99
+ end
100
+ end
101
+
102
+ refute model.valid?
103
+ refute_empty model.errors[:resizing_picture]
104
+ assert_nil model.read_attribute(:resizing_picture)
105
+ end
106
+
107
+ def test_extension_of_file_name_is_used_when_content_type_is_unknown
108
+ # application/octet-stream は型の情報を持たないので、ファイル名の拡張子 (jpg) で判定される
109
+ model = TestModelWithJpegAllowlist.new
110
+ url = 'https://example.com/images/photo.jpg'
111
+ remote_file = sample_remote_file(url, content_type: 'application/octet-stream')
112
+
113
+ assert_vcr_requests_count 'carrier_wave_test/save', 1 do
114
+ with_stubbed_download(remote_file) do
115
+ model.remote_resizing_picture_url = url
116
+ end
117
+ end
118
+
119
+ assert model.valid?, model.errors.full_messages.join(', ')
120
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
121
+ end
122
+
123
+ def test_extension_of_file_name_is_used_when_content_type_is_not_registered
124
+ # MIME::Types / MiniMime に登録されていない content_type でもエラーにならず、
125
+ # ファイル名の拡張子 (jpg) で判定される
126
+ model = TestModelWithJpegAllowlist.new
127
+ url = 'https://example.com/images/photo.jpg'
128
+ remote_file = sample_remote_file(url, content_type: 'image/x-unregistered-type')
129
+
130
+ assert_vcr_requests_count 'carrier_wave_test/save', 1 do
131
+ with_stubbed_download(remote_file) do
132
+ model.remote_resizing_picture_url = url
133
+ end
134
+ end
135
+
136
+ assert model.valid?, model.errors.full_messages.join(', ')
137
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
138
+ end
139
+
140
+ def test_content_type_parameters_are_ignored
141
+ # `image/jpeg; charset=binary` のようなパラメータ付きの値でも image/jpeg として判定される
142
+ model = TestModelWithJpegAllowlist.new
143
+ remote_file = sample_remote_file(RESIZING_IMAGE_URL, content_type: 'image/jpeg; charset=binary')
144
+
145
+ assert_vcr_requests_count 'carrier_wave_test/save', 1 do
146
+ with_stubbed_download(remote_file) do
147
+ model.remote_resizing_picture_url = RESIZING_IMAGE_URL
148
+ end
149
+ end
150
+
151
+ assert model.valid?, model.errors.full_messages.join(', ')
152
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
153
+ end
154
+
155
+ def test_content_type_takes_precedence_over_extension_of_uploaded_file
156
+ # ローカルからのアップロードでも、ファイル名の拡張子 (jpg) より content_type (image/png) が優先される
157
+ model = TestModelWithJpegAllowlist.new
158
+ file = File.open('test/data/images/sample1.jpg', 'r')
159
+ uploaded_file = ActionDispatch::Http::UploadedFile.new(filename: 'sample1.jpg', type: 'image/png', tempfile: file)
160
+
161
+ assert_vcr_no_requests 'carrier_wave_test/save' do
162
+ model.resizing_picture = uploaded_file
163
+ end
164
+
165
+ refute model.valid?
166
+ assert_nil model.read_attribute(:resizing_picture)
167
+ end
168
+
169
+ def test_uploaded_file_matching_its_content_type_is_accepted
170
+ # 拡張子と content_type が一致する通常のアップロードは、これまで通り受け付けられる
171
+ model = TestModelWithJpegAllowlist.new
172
+
173
+ assert_vcr_requests_count 'carrier_wave_test/save', 1 do
174
+ model.resizing_picture = sample_uploaded_file
175
+ end
176
+
177
+ assert model.valid?, model.errors.full_messages.join(', ')
178
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
179
+ end
180
+
181
+ # ============================================================
182
+ # Resizing の設計に合わないコールバックが発火しないこと
183
+ # ============================================================
184
+
185
+ def test_versions_are_not_uploaded_again
186
+ # ResizingUploader は version :small を持つが、version は配信時に変換されるので
187
+ # cache_versions! による追加アップロードは発生しない
188
+ model = TestModel.new
189
+
190
+ assert_vcr_requests_count 'carrier_wave_test/save', 1 do
191
+ model.resizing_picture = sample_uploaded_file
192
+ end
193
+
194
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
195
+ end
196
+
197
+ def test_processors_are_not_executed_on_upload
198
+ # process は配信 URL の transform 定義なので、uploader のメソッドとしては存在しない。
199
+ # process! が発火すると NoMethodError になる
200
+ model = TestModelWithUndefinedProcessor.new
201
+
202
+ assert_vcr_requests_count 'carrier_wave_test/save', 1 do
203
+ model.resizing_picture = sample_uploaded_file
204
+ end
205
+
206
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
207
+ end
208
+
209
+ private
210
+
211
+ # 画像の代入時に POST が発行されず、モデルが integrity error で invalid になることを確認する
212
+ def assert_rejected_before_upload(model_class)
213
+ model = model_class.new
214
+
215
+ assert_vcr_no_requests 'carrier_wave_test/save' do
216
+ model.resizing_picture = sample_uploaded_file
217
+ end
218
+
219
+ refute model.valid?, "#{model_class} should be invalid after the file was rejected"
220
+ refute_empty model.errors[:resizing_picture]
221
+ assert_nil model.read_attribute(:resizing_picture)
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Resizing
6
+ # :cache コールバックに渡されるファイル (CallbackFile) の拡張子が content_type から決まることをテストする
7
+ class CarrierWaveCallbackFileTest < Minitest::Test
8
+ # Resizing の公開 URL の最後のセグメント (バージョン文字列)。ドットを含むので
9
+ # ファイル名としては `Fv_Q` が拡張子に見える
10
+ RESIZING_FILENAME = 'v0cRq7Yb2mZt9LxA3wN8eKd5pHs1.Fv_Q'
11
+
12
+ def test_original_filename_is_nil_when_the_file_has_no_name
13
+ file = Resizing::CarrierWave::CallbackFile.new(StringIO.new('data'))
14
+
15
+ assert_nil file.original_filename
16
+ assert_nil file.extension
17
+ end
18
+
19
+ def test_extension_follows_the_content_type
20
+ file = build_file(RESIZING_FILENAME, 'image/jpeg')
21
+
22
+ assert_equal 'v0cRq7Yb2mZt9LxA3wN8eKd5pHs1.jpeg', file.original_filename
23
+ assert_equal 'jpeg', file.extension
24
+ end
25
+
26
+ def test_file_name_is_kept_when_its_extension_belongs_to_the_content_type
27
+ # jpg は image/jpeg の拡張子の一つなので、jpeg に付け替えられない (大文字小文字も区別しない)
28
+ file = build_file('photo.JPG', 'image/jpeg')
29
+
30
+ assert_equal 'photo.JPG', file.original_filename
31
+ assert_equal 'JPG', file.extension
32
+ end
33
+
34
+ def test_file_name_is_kept_when_the_content_type_is_not_registered
35
+ file = build_file('photo.jpg', 'image/x-unregistered-type')
36
+
37
+ assert_equal 'photo.jpg', file.original_filename
38
+ end
39
+
40
+ def test_mini_mime_is_used_when_mime_types_is_not_loaded
41
+ file = build_file(RESIZING_FILENAME, 'image/jpeg')
42
+
43
+ file.stub(:mime_types_available?, false) do
44
+ assert_equal 'v0cRq7Yb2mZt9LxA3wN8eKd5pHs1.jpeg', file.original_filename
45
+ end
46
+ end
47
+
48
+ def test_file_name_is_kept_when_mini_mime_does_not_know_the_content_type
49
+ file = build_file('photo.jpg', 'image/x-unregistered-type')
50
+
51
+ file.stub(:mime_types_available?, false) do
52
+ assert_equal 'photo.jpg', file.original_filename
53
+ end
54
+ end
55
+
56
+ def test_file_name_is_kept_when_no_lookup_library_is_loaded
57
+ file = build_file(RESIZING_FILENAME, 'image/jpeg')
58
+
59
+ file.stub(:mime_types_available?, false) do
60
+ file.stub(:mini_mime_available?, false) do
61
+ assert_equal RESIZING_FILENAME, file.original_filename
62
+ end
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def build_file(filename, content_type)
69
+ uploaded_file = ActionDispatch::Http::UploadedFile.new(
70
+ filename: filename,
71
+ type: content_type,
72
+ tempfile: File.open('test/data/images/sample1.jpg', 'r')
73
+ )
74
+ Resizing::CarrierWave::CallbackFile.new(uploaded_file)
75
+ end
76
+ end
77
+ end
@@ -5,20 +5,13 @@ require 'test_helper'
5
5
  module Resizing
6
6
  class CarrierWaveTest < Minitest::Test
7
7
  include VCRRequestAssertions
8
+ include ResizingTestConfiguration
8
9
 
9
10
  def setup
10
11
  TestModel.delete_all
11
12
  TestJPGModel.delete_all
12
13
 
13
- @configuration_template = {
14
- image_host: 'http://192.168.56.101:5000',
15
- video_host: 'http://192.168.56.101:5000',
16
- project_id: 'e06e710d-f026-4dcf-b2c0-eab0de8bb83f',
17
- secret_token: 'ewbym2r1pk49x1d2lxdbiiavnqp25j2kh00hsg3koy0ppm620x5mhlmgl3rq5ci8',
18
- open_timeout: 10,
19
- response_timeout: 20
20
- }
21
- Resizing.configure = @configuration_template
14
+ configure_resizing
22
15
  end
23
16
 
24
17
  def teardown; end
@@ -163,11 +156,6 @@ module Resizing
163
156
  assert_instance_of Resizing::CarrierWave::Storage::File, file
164
157
  end
165
158
 
166
- def expect_url
167
- 'http://192.168.56.101:5000/projects/e06e710d-f026-4dcf-b2c0-eab0de8bb83f/' \
168
- 'upload/images/14ea7aac-a194-4330-931f-6b562aec413d/v_8c5lEhDB5RT3PZp1Fn5PYGm9YVx_x0e'
169
- end
170
-
171
159
  def prepare_model(model_class)
172
160
  result = nil
173
161
  VCR.use_cassette 'carrier_wave_test/save', record: :once do
@@ -177,18 +165,6 @@ module Resizing
177
165
  result
178
166
  end
179
167
 
180
- # モデルにサンプル画像を添付するヘルパーメソッド
181
- # VCRカセット内で呼び出す必要がある
182
- def attach_sample_image(model)
183
- file = File.open('test/data/images/sample1.jpg', 'r')
184
- uploaded_file = ActionDispatch::Http::UploadedFile.new(
185
- filename: File.basename(file.path),
186
- type: 'image/jpeg',
187
- tempfile: file
188
- )
189
- model.resizing_picture = uploaded_file
190
- end
191
-
192
168
  # TestModelWithCallbackTracking 用のヘルパーメソッド
193
169
  def prepare_tracking_model
194
170
  prepare_model(TestModelWithCallbackTracking)
@@ -462,5 +438,204 @@ module Resizing
462
438
  # コールバックが正しい順序で呼ばれたことを確認
463
439
  assert_equal %i[before_destroy after_destroy destroy_commit], model.callback_log
464
440
  end
441
+
442
+ # ============================================================
443
+ # DB から再読込したモデルに対する操作 (retrieve_from_store! 経由)
444
+ # ============================================================
445
+
446
+ def test_url_of_freshly_loaded_model_matches_saved_url
447
+ model = prepare_model TestModel
448
+ model.save!
449
+
450
+ loaded = TestModel.find(model.id)
451
+
452
+ assert_equal "#{expect_url}/", loaded.resizing_picture_url
453
+ assert_equal "#{expect_url}/c_fill,w_40,h_40", loaded.resizing_picture_url(:small)
454
+ refute loaded.resizing_picture.blank?
455
+ end
456
+
457
+ def test_remove_on_freshly_loaded_model_deletes_remote_image_and_clears_column
458
+ model = prepare_model TestModel
459
+ model.save!
460
+
461
+ loaded = TestModel.find(model.id)
462
+
463
+ assert_vcr_requests_made 'carrier_wave_test/remove_resizing_picture' do
464
+ loaded.remove_resizing_picture!
465
+ loaded.save!
466
+ end
467
+
468
+ assert_nil loaded.read_attribute(:resizing_picture)
469
+ assert_nil loaded.resizing_picture_url
470
+ assert_nil TestModel.find(model.id).read_attribute(:resizing_picture)
471
+ end
472
+
473
+ def test_remove_flag_on_freshly_loaded_model_deletes_remote_image_and_clears_column
474
+ model = prepare_model TestModel
475
+ model.save!
476
+
477
+ loaded = TestModel.find(model.id)
478
+ loaded.remove_resizing_picture = true
479
+
480
+ assert_vcr_requests_made 'carrier_wave_test/remove_resizing_picture' do
481
+ loaded.save!
482
+ end
483
+
484
+ assert loaded.resizing_picture.blank?
485
+ assert_nil TestModel.find(model.id).read_attribute(:resizing_picture)
486
+ end
487
+
488
+ def test_destroy_on_freshly_loaded_model_deletes_remote_image
489
+ model = prepare_model TestModel
490
+ model.save!
491
+
492
+ loaded = TestModel.find(model.id)
493
+
494
+ assert_vcr_requests_made 'carrier_wave_test/remove_resizing_picture' do
495
+ ActiveRecord::Base.transaction do
496
+ loaded.destroy!
497
+ end
498
+ end
499
+
500
+ assert loaded.destroyed?
501
+ assert_nil TestModel.find_by(id: model.id)
502
+ end
503
+
504
+ def test_remove_persists_nil_to_database
505
+ model = prepare_model TestModel
506
+ model.save!
507
+
508
+ assert_vcr_requests_made 'carrier_wave_test/remove_resizing_picture' do
509
+ model.remove_resizing_picture!
510
+ model.save!
511
+ end
512
+
513
+ assert_nil TestModel.find(model.id).read_attribute(:resizing_picture)
514
+ end
515
+
516
+ # ============================================================
517
+ # 代入時の挙動
518
+ # ============================================================
519
+
520
+ def test_column_is_set_immediately_after_assignment
521
+ model = TestModel.new
522
+
523
+ assert_vcr_requests_made 'carrier_wave_test/save' do
524
+ attach_sample_image(model)
525
+ end
526
+
527
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
528
+ assert_equal expect_identifier, model.resizing_picture.identifier
529
+ assert_equal expect_identifier, model.resizing_picture.file.public_id.to_s
530
+ assert_equal 'image/jpeg', model.resizing_picture.file.content_type
531
+ assert model.resizing_picture.present?
532
+ end
533
+
534
+ def test_save_after_assignment_does_not_upload_again
535
+ model = prepare_model TestModel
536
+
537
+ # 代入時に既にアップロード済みなので、save! で再度 POST は発行されない
538
+ assert_vcr_no_requests 'carrier_wave_test/save' do
539
+ model.save!
540
+ end
541
+
542
+ assert_equal expect_identifier, TestModel.find(model.id).read_attribute(:resizing_picture)
543
+ end
544
+
545
+ def test_assigning_nil_keeps_existing_image
546
+ model = prepare_model TestModel
547
+ model.save!
548
+
549
+ assert_vcr_no_requests 'carrier_wave_test/save' do
550
+ model.resizing_picture = nil
551
+ model.save!
552
+ end
553
+
554
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
555
+ assert_equal "#{expect_url}/", model.resizing_picture_url
556
+ end
557
+
558
+ def test_assigning_blank_string_keeps_existing_image
559
+ model = prepare_model TestModel
560
+ model.save!
561
+
562
+ assert_vcr_no_requests 'carrier_wave_test/save' do
563
+ model.resizing_picture = ''
564
+ model.save!
565
+ end
566
+
567
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
568
+ end
569
+
570
+ def test_assigning_plain_file_object_uploads_image
571
+ model = TestModel.new
572
+
573
+ assert_vcr_requests_made 'carrier_wave_test/save' do
574
+ model.resizing_picture = File.open('test/data/images/sample1.jpg', 'r')
575
+ end
576
+
577
+ assert_equal expect_identifier, model.read_attribute(:resizing_picture)
578
+ end
579
+
580
+ def test_default_url_is_returned_after_remove
581
+ TestModelWithDefaultURL.delete_all
582
+ model = prepare_model TestModelWithDefaultURL
583
+ model.save!
584
+ refute_equal 'http://example.com/test.jpg', model.resizing_picture_url
585
+
586
+ assert_vcr_requests_made 'carrier_wave_test/remove_resizing_picture' do
587
+ model.remove_resizing_picture!
588
+ model.save!
589
+ end
590
+
591
+ assert_equal 'http://example.com/test.jpg', model.resizing_picture_url
592
+ end
593
+
594
+ # ============================================================
595
+ # 画像更新時の永続化
596
+ # ============================================================
597
+
598
+ def test_updated_image_is_persisted_and_old_image_deleted
599
+ # update_image カセット: POST(old) -> POST(new) -> DELETE(old)
600
+ model = nil
601
+ assert_vcr_requests_made 'carrier_wave_test/update_image' do
602
+ model = TestModel.new
603
+ model.resizing_picture = File.open('test/data/images/sample1.jpg', 'r')
604
+ model.save!
605
+
606
+ model.resizing_picture = File.open('test/data/images/sample1.jpg', 'r')
607
+ ActiveRecord::Base.transaction do
608
+ model.save!
609
+ end
610
+ end
611
+
612
+ loaded = TestModel.find(model.id)
613
+ assert_equal(
614
+ '/projects/e06e710d-f026-4dcf-b2c0-eab0de8bb83f/upload/images/new-image-id-2222-2222-222222222222/v2',
615
+ loaded.read_attribute(:resizing_picture)
616
+ )
617
+ assert_equal(
618
+ 'http://192.168.56.101:5000/projects/e06e710d-f026-4dcf-b2c0-eab0de8bb83f/upload/images/new-image-id-2222-2222-222222222222/v2/',
619
+ loaded.resizing_picture_url
620
+ )
621
+ end
622
+
623
+ def test_previous_changes_after_update_records_old_and_new_identifier
624
+ model = nil
625
+ assert_vcr_requests_made 'carrier_wave_test/update_image' do
626
+ model = TestModel.new
627
+ model.resizing_picture = File.open('test/data/images/sample1.jpg', 'r')
628
+ model.save!
629
+
630
+ model.resizing_picture = File.open('test/data/images/sample1.jpg', 'r')
631
+ ActiveRecord::Base.transaction do
632
+ model.save!
633
+ end
634
+ end
635
+
636
+ old_value, new_value = model.previous_changes['resizing_picture']
637
+ assert_match(/old-image-id/, old_value)
638
+ assert_match(/new-image-id/, new_value)
639
+ end
465
640
  end
466
641
  end