kithe 2.0.0.pre.alpha2 → 2.0.0.pre.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/jobs/kithe/create_derivatives_job.rb +2 -2
- data/app/models/kithe/asset.rb +82 -154
- data/app/models/kithe/asset/derivative_creator.rb +32 -62
- data/app/models/kithe/asset/derivative_definition.rb +12 -13
- data/app/models/kithe/asset/set_shrine_uploader.rb +64 -0
- data/app/models/kithe/collection.rb +0 -6
- data/app/models/kithe/model.rb +0 -21
- data/app/models/kithe/work.rb +0 -5
- data/app/uploaders/kithe/asset_uploader.rb +15 -78
- data/lib/kithe/version.rb +4 -1
- data/lib/shrine/plugins/kithe_checksum_signatures.rb +41 -0
- data/lib/shrine/plugins/kithe_controllable_backgrounding.rb +53 -0
- data/lib/shrine/plugins/kithe_derivative_definitions.rb +101 -0
- data/lib/shrine/plugins/kithe_derivatives.rb +54 -0
- data/lib/shrine/plugins/kithe_determine_mime_type.rb +39 -0
- data/lib/shrine/plugins/kithe_persisted_derivatives.rb +161 -0
- data/lib/shrine/plugins/kithe_promotion_callbacks.rb +4 -0
- data/lib/shrine/plugins/kithe_promotion_directives.rb +33 -3
- data/lib/shrine/plugins/kithe_storage_location.rb +53 -4
- data/lib/tasks/kithe_tasks.rake +22 -15
- data/spec/dummy/log/development.log +867 -0
- data/spec/dummy/log/test.log +26005 -0
- data/spec/models/kithe/asset/asset_derivatives_spec.rb +137 -0
- data/spec/models/kithe/asset/asset_promotion_hooks_spec.rb +26 -5
- data/spec/models/kithe/asset/set_shrine_uploader_spec.rb +39 -0
- data/spec/models/kithe/asset_spec.rb +9 -59
- data/spec/models/kithe/model_spec.rb +0 -32
- data/spec/shrine/kithe_accept_remote_url_spec.rb +49 -0
- data/spec/shrine/kithe_checksum_signatures_spec.rb +63 -0
- data/spec/shrine/kithe_derivative_definitions_spec.rb +303 -0
- data/spec/shrine/kithe_persisted_derivatives_spec.rb +424 -0
- data/spec/shrine/kithe_storage_location_spec.rb +43 -15
- data/spec/spec_helper.rb +7 -6
- data/spec/test_support/images/3x3_pixel.jpg +0 -0
- data/spec/test_support/shrine_spec_support.rb +2 -1
- metadata +23 -23
- data/app/models/kithe/asset/derivative_updater.rb +0 -119
- data/app/models/kithe/derivative.rb +0 -15
- data/app/uploaders/kithe/derivative_uploader.rb +0 -48
- data/spec/models/kithe/asset/asset_create_derivatives_spec.rb +0 -320
- data/spec/models/kithe/derivative_spec.rb +0 -168
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'shrine/plugins/kithe_checksum_signatures'
|
3
|
+
|
4
|
+
# This kithe plugin is optional, let's make sure it works how we expect
|
5
|
+
describe Shrine::Plugins::KitheChecksumSignatures, queue_adpater: :inline do
|
6
|
+
temporary_class("ChecksumUploader") do
|
7
|
+
Class.new(Kithe::AssetUploader) do
|
8
|
+
plugin :kithe_checksum_signatures
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
temporary_class("ChecksumAsset") do
|
13
|
+
Class.new(Kithe::Asset) do
|
14
|
+
set_shrine_uploader(ChecksumUploader)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
around do |example|
|
19
|
+
original = Kithe::Asset.promotion_directives
|
20
|
+
Kithe::Asset.promotion_directives = { promote: :inline }
|
21
|
+
|
22
|
+
example.run
|
23
|
+
|
24
|
+
Kithe::Asset.promotion_directives = original
|
25
|
+
end
|
26
|
+
|
27
|
+
it "provides checksum metadata after promotion" do
|
28
|
+
asset = ChecksumAsset.create!(title: "test", file: StringIO.new("test"))
|
29
|
+
asset.reload
|
30
|
+
|
31
|
+
expect(asset).to be_stored
|
32
|
+
expect(asset.file.metadata.slice("md5", "sha1", "sha512")).to all(be_present)
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "without promotion" do
|
36
|
+
around do |example|
|
37
|
+
original = Kithe::Asset.promotion_directives
|
38
|
+
Kithe::Asset.promotion_directives = { promote: false }
|
39
|
+
|
40
|
+
example.run
|
41
|
+
|
42
|
+
Kithe::Asset.promotion_directives = original
|
43
|
+
end
|
44
|
+
|
45
|
+
it "does not extract checksum metadata on cache" do
|
46
|
+
asset = ChecksumAsset.create!(title: "test", file: StringIO.new("test"))
|
47
|
+
asset.reload
|
48
|
+
|
49
|
+
expect(asset).not_to be_stored
|
50
|
+
expect(asset.file.metadata.slice("md5", "sha1", "sha512")).not_to include(be_present)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "derivatives" do
|
55
|
+
it "do not get checksum metadata" do
|
56
|
+
asset = ChecksumAsset.create!(title: "test", file: StringIO.new("test"))
|
57
|
+
asset.update_derivative("test", StringIO.new("test deriv"))
|
58
|
+
|
59
|
+
expect(asset.file_derivatives[:test]).to be_present
|
60
|
+
expect(asset.file_derivatives[:test].metadata.slice("md5", "sha1", "sha512")).not_to include(be_present)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,303 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
# We just test with a Kithe::Asset class, too much trouble to try to isolate, not
|
4
|
+
# worth it I think.
|
5
|
+
describe "Shrine::Plugins::KitheDerivativeDefinitions", queue_adapter: :test do
|
6
|
+
# promotion inline, disable auto derivatives
|
7
|
+
around do |example|
|
8
|
+
original = Kithe::Asset.promotion_directives
|
9
|
+
Kithe::Asset.promotion_directives = { promote: :inline, create_derivatives: false }
|
10
|
+
|
11
|
+
example.run
|
12
|
+
Kithe::Asset.promotion_directives = original
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:a_jpg_deriv_file) { Kithe::Engine.root.join("spec/test_support/images/2x2_pixel.jpg") }
|
16
|
+
|
17
|
+
temporary_class("CustomUploader") do
|
18
|
+
deriv_src_path = a_jpg_deriv_file
|
19
|
+
|
20
|
+
Class.new(Kithe::AssetUploader) do
|
21
|
+
self::Attacher.define_derivative(:some_data) do |original_file|
|
22
|
+
StringIO.new("some one data")
|
23
|
+
end
|
24
|
+
|
25
|
+
self::Attacher.define_derivative(:a_jpg) do |original_file|
|
26
|
+
FileUtils.cp(deriv_src_path,
|
27
|
+
Kithe::Engine.root.join("spec/test_support/images/2x2_pixel-TEMP.jpg"))
|
28
|
+
|
29
|
+
File.open(Kithe::Engine.root.join("spec/test_support/images/2x2_pixel-TEMP.jpg"))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
temporary_class("CustomAsset") do
|
35
|
+
Class.new(Kithe::Asset) do
|
36
|
+
set_shrine_uploader(CustomUploader)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:asset) do
|
41
|
+
CustomAsset.create(title: "test",
|
42
|
+
file: File.open(Kithe::Engine.root.join("spec/test_support/images/1x1_pixel.jpg"))
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "normalizes string key to symbol" do
|
47
|
+
CustomUploader::Attacher.define_derivative("started_string") { |io| }
|
48
|
+
expect(CustomUploader::Attacher.kithe_derivative_definitions.collect(&:key)).to include(:started_string)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "builds derivatives" do
|
52
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives)
|
53
|
+
|
54
|
+
one_deriv = asset.file_derivatives[:some_data]
|
55
|
+
expect(one_deriv).to be_present
|
56
|
+
expect(one_deriv.read).to eq("some one data")
|
57
|
+
|
58
|
+
jpg_deriv = asset.file_derivatives[:a_jpg]
|
59
|
+
expect(jpg_deriv.read).to eq(File.binread(a_jpg_deriv_file))
|
60
|
+
expect(jpg_deriv.storage_key).to eq(:kithe_derivatives)
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "attacher argument to block" do
|
64
|
+
let(:monitoring_proc) do
|
65
|
+
proc do |original_file, attacher:|
|
66
|
+
expect(original_file.kind_of?(File) || original_file.kind_of?(Tempfile)).to be(true)
|
67
|
+
expect(original_file.path).to be_present
|
68
|
+
expect(original_file.read).to eq(asset.file.read)
|
69
|
+
|
70
|
+
expect(attacher).to be_present
|
71
|
+
expect(attacher).to be_kind_of(Shrine::Attacher)
|
72
|
+
expect(attacher.record).to eq(asset)
|
73
|
+
expect(attacher.file).to be_kind_of(Shrine::UploadedFile)
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
before do
|
79
|
+
# hacky confusing way to set this up for testing, sorry.
|
80
|
+
CustomUploader::Attacher.kithe_derivative_definitions = []
|
81
|
+
CustomUploader::Attacher.define_derivative(:some_data, &monitoring_proc)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "as expected" do
|
85
|
+
expect(monitoring_proc).to receive(:call).and_call_original
|
86
|
+
|
87
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives)
|
88
|
+
expect(asset.file_derivatives.length).to eq(0)
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "as **kwargs" do
|
92
|
+
let(:monitoring_proc) do
|
93
|
+
proc do |original_file, **kwargs|
|
94
|
+
expect(original_file.kind_of?(File) || original_file.kind_of?(Tempfile)).to be(true)
|
95
|
+
expect(original_file.path).to be_present
|
96
|
+
expect(original_file.read).to eq(asset.file.read)
|
97
|
+
|
98
|
+
# It really has to be a local file with a path, not just an IO.
|
99
|
+
# Kithe wants to guarantee this, whether or not shrine does.
|
100
|
+
expect(original_file).to respond_to(:path)
|
101
|
+
|
102
|
+
expect(kwargs[:attacher]).to be_present
|
103
|
+
expect(kwargs[:attacher]).to eq(asset.file_attacher)
|
104
|
+
|
105
|
+
nil
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "as expected" do
|
110
|
+
expect(monitoring_proc).to receive(:call).and_call_original
|
111
|
+
|
112
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives)
|
113
|
+
expect(asset.file_derivatives.length).to eq(0)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
describe "default_create false" do
|
120
|
+
let(:monitoring_proc) { proc { |asset| } }
|
121
|
+
|
122
|
+
before do
|
123
|
+
# hacky confusing way to set this up for testing, sorry.
|
124
|
+
CustomUploader::Attacher.kithe_derivative_definitions = []
|
125
|
+
CustomUploader::Attacher.define_derivative(:some_data, default_create: false, &monitoring_proc)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "is not run automatically" do
|
129
|
+
expect(monitoring_proc).not_to receive(:call)
|
130
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "only/except" do
|
135
|
+
let(:monitoring_proc1) { proc { |asset| StringIO.new("one") } }
|
136
|
+
let(:monitoring_proc2) { proc { |asset| StringIO.new("two") } }
|
137
|
+
let(:monitoring_proc3) { proc { |asset| StringIO.new("three") } }
|
138
|
+
|
139
|
+
before do
|
140
|
+
# hacky confusing way to set this up for testing, sorry.
|
141
|
+
CustomUploader::Attacher.kithe_derivative_definitions = []
|
142
|
+
CustomUploader::Attacher.define_derivative(:one, default_create: false, &monitoring_proc1)
|
143
|
+
CustomUploader::Attacher.define_derivative(:two, &monitoring_proc2)
|
144
|
+
CustomUploader::Attacher.define_derivative(:three, &monitoring_proc2)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "can call with only" do
|
148
|
+
expect(monitoring_proc1).to receive(:call).and_call_original
|
149
|
+
expect(monitoring_proc2).to receive(:call).and_call_original
|
150
|
+
expect(monitoring_proc3).not_to receive(:call)
|
151
|
+
|
152
|
+
# except string or symbol
|
153
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives, only: [:one, "two"])
|
154
|
+
|
155
|
+
expect(asset.file_derivatives.keys).to match([:one, :two])
|
156
|
+
end
|
157
|
+
|
158
|
+
it "can call with except" do
|
159
|
+
expect(monitoring_proc1).not_to receive(:call)
|
160
|
+
expect(monitoring_proc2).to receive(:call).and_call_original
|
161
|
+
expect(monitoring_proc3).not_to receive(:call)
|
162
|
+
|
163
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives, except: [:three])
|
164
|
+
|
165
|
+
# :one was default_create:false, and we said except: :three
|
166
|
+
expect(asset.file_derivatives.keys).to eq([:two])
|
167
|
+
end
|
168
|
+
|
169
|
+
it "can call with except as string" do
|
170
|
+
expect(monitoring_proc1).not_to receive(:call)
|
171
|
+
expect(monitoring_proc2).to receive(:call).and_call_original
|
172
|
+
expect(monitoring_proc3).not_to receive(:call)
|
173
|
+
|
174
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives, except: ["three"])
|
175
|
+
|
176
|
+
# :one was default_create:false, and we said except: :three
|
177
|
+
expect(asset.file_derivatives.keys).to eq([:two])
|
178
|
+
end
|
179
|
+
|
180
|
+
it "can call with only and except" do
|
181
|
+
expect(monitoring_proc1).to receive(:call).and_call_original
|
182
|
+
expect(monitoring_proc2).to receive(:call).and_call_original
|
183
|
+
expect(monitoring_proc3).not_to receive(:call)
|
184
|
+
|
185
|
+
# string version of except why not
|
186
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives, only: [:one, :two], except: :three)
|
187
|
+
|
188
|
+
expect(asset.file_derivatives.keys).to eq([:one, :two])
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
describe "content_type filters" do
|
194
|
+
before do
|
195
|
+
# hacky confusing way to set this up for testing, sorry.
|
196
|
+
CustomUploader::Attacher.kithe_derivative_definitions = []
|
197
|
+
CustomUploader::Attacher.define_derivative(:never_called, content_type: "nothing/nothing") { |o| StringIO.new("never") }
|
198
|
+
CustomUploader::Attacher.define_derivative(:gated_positive, content_type: "image/jpeg") { |o| StringIO.new("gated positive") }
|
199
|
+
CustomUploader::Attacher.define_derivative(:gated_positive_main_type, content_type: "image") { |o| StringIO.new("gated positive") }
|
200
|
+
end
|
201
|
+
|
202
|
+
it "does not call if content type does not match" do
|
203
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives)
|
204
|
+
expect(asset.file_derivatives.keys).not_to include(:never_called)
|
205
|
+
end
|
206
|
+
|
207
|
+
it "calls for exact content type match" do
|
208
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives)
|
209
|
+
expect(asset.file_derivatives.keys).to include(:gated_positive)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "calls for main content type match" do
|
213
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives)
|
214
|
+
expect(asset.file_derivatives.keys).to include(:gated_positive_main_type)
|
215
|
+
end
|
216
|
+
|
217
|
+
describe "as array" do
|
218
|
+
before do
|
219
|
+
# hacky confusing way to set this up for testing, sorry.
|
220
|
+
CustomUploader::Attacher.kithe_derivative_definitions = []
|
221
|
+
CustomUploader::Attacher.define_derivative(:never_called, content_type: ["nothing/nothing", "also/nothing"]) { |o| StringIO.new("never") }
|
222
|
+
CustomUploader::Attacher.define_derivative(:gated_positive, content_type: ["image/jpeg", "something/else"]) { |o| StringIO.new("gated positive") }
|
223
|
+
end
|
224
|
+
|
225
|
+
it "calls for one match" do
|
226
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives)
|
227
|
+
expect(asset.file_derivatives.keys).to eq([:gated_positive])
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "conflicting types" do
|
232
|
+
let(:unfiltered) { proc { |asset| StringIO.new("unfiltered") } }
|
233
|
+
let(:image) { proc { |asset| StringIO.new("image") } }
|
234
|
+
let(:image_jpeg) { proc { |asset| StringIO.new("image/jpeg") } }
|
235
|
+
|
236
|
+
before do
|
237
|
+
# hacky confusing way to set this up for testing, sorry.
|
238
|
+
CustomUploader::Attacher.kithe_derivative_definitions = []
|
239
|
+
CustomUploader::Attacher.define_derivative(:key, &unfiltered)
|
240
|
+
CustomUploader::Attacher.define_derivative(:key, content_type: "image/jpeg", &image_jpeg)
|
241
|
+
CustomUploader::Attacher.define_derivative(:key, content_type: "image", &image)
|
242
|
+
end
|
243
|
+
|
244
|
+
it "takes most specific" do
|
245
|
+
expect(unfiltered).not_to receive(:call)
|
246
|
+
expect(image).not_to receive(:call)
|
247
|
+
expect(image_jpeg).to receive(:call).and_call_original
|
248
|
+
|
249
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives)
|
250
|
+
expect(asset.file_derivatives.count).to eq(1)
|
251
|
+
|
252
|
+
|
253
|
+
expect(asset.file_derivatives.keys).to eq([:key])
|
254
|
+
expect(asset.file_derivatives[:key].read). to eq("image/jpeg")
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
describe "lazy creation" do
|
260
|
+
before do
|
261
|
+
# Create existing derivatives for existing definitions, which we assume exist
|
262
|
+
expect(CustomUploader::Attacher.kithe_derivative_definitions).to be_present
|
263
|
+
|
264
|
+
CustomUploader::Attacher.kithe_derivative_definitions.collect(&:key).each do |key|
|
265
|
+
asset.file_attacher.add_persisted_derivatives({key => StringIO.new("#{key} original")})
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
it "does not re-create" do
|
270
|
+
derivatives_pre_creation = asset.file_derivatives
|
271
|
+
|
272
|
+
asset.file_attacher.create_derivatives(:kithe_derivatives, lazy: true)
|
273
|
+
derivatives_post_creation = asset.file_derivatives
|
274
|
+
|
275
|
+
expect(derivatives_post_creation).to eq(derivatives_pre_creation)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
describe "#remove_derivative_definition!" do
|
280
|
+
let(:defined_derivative_key) do
|
281
|
+
CustomUploader::Attacher.defined_derivative_keys.first.tap do |key|
|
282
|
+
expect(key).to be_present
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
it "can remove by string" do
|
287
|
+
expect {
|
288
|
+
CustomUploader::Attacher.remove_derivative_definition!(defined_derivative_key.to_s)
|
289
|
+
}.to change { CustomUploader::Attacher.defined_derivative_keys.count }.from(2).to(1)
|
290
|
+
end
|
291
|
+
|
292
|
+
it "can remove by symbol" do
|
293
|
+
expect {
|
294
|
+
CustomUploader::Attacher.remove_derivative_definition!(defined_derivative_key.to_sym)
|
295
|
+
}.to change { CustomUploader::Attacher.defined_derivative_keys.count }.from(2).to(1)
|
296
|
+
end
|
297
|
+
|
298
|
+
it "can remove multiple args" do
|
299
|
+
CustomUploader::Attacher.remove_derivative_definition!(*CustomUploader::Attacher.defined_derivative_keys)
|
300
|
+
expect(CustomUploader::Attacher.defined_derivative_keys).to eq([])
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
@@ -0,0 +1,424 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'shrine/plugins/kithe_persisted_derivatives'
|
3
|
+
|
4
|
+
# We just test with a Kithe::Asset class, too much trouble to try to isolate, not
|
5
|
+
# worth it I think.
|
6
|
+
describe Shrine::Plugins::KithePersistedDerivatives, queue_adapter: :test do
|
7
|
+
# promotion inline, disable auto derivatives
|
8
|
+
around do |example|
|
9
|
+
original = Kithe::Asset.promotion_directives
|
10
|
+
Kithe::Asset.promotion_directives = { promote: :inline, create_derivatives: false }
|
11
|
+
|
12
|
+
example.run
|
13
|
+
Kithe::Asset.promotion_directives = original
|
14
|
+
end
|
15
|
+
|
16
|
+
# Need to make a new copy, because shrine likes deleting derivatives!
|
17
|
+
def sample_deriv_file!(path = Kithe::Engine.root.join("spec/test_support/images/1x1_pixel.jpg"))
|
18
|
+
tempfile = Tempfile.new
|
19
|
+
IO.copy_stream(File.open(path), tempfile)
|
20
|
+
|
21
|
+
tempfile
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:sample_orig_path) { Kithe::Engine.root.join("spec/test_support/images/2x2_pixel.jpg") }
|
25
|
+
let(:another_sample_orig_path) { Kithe::Engine.root.join("spec/test_support/images/1x1_pixel.jpg") }
|
26
|
+
|
27
|
+
let(:asset) { Kithe::Asset.create!(title: "test", file: File.open(sample_orig_path))}
|
28
|
+
|
29
|
+
describe "#add_persisted_derivatives" do
|
30
|
+
it "can add and persist" do
|
31
|
+
asset.file_attacher.add_persisted_derivatives(sample: sample_deriv_file!)
|
32
|
+
|
33
|
+
expect(asset.changed?).to be(false)
|
34
|
+
expect(asset.file_derivatives[:sample]).to be_present
|
35
|
+
expect(asset.file_derivatives[:sample].storage_key).to eq(:kithe_derivatives)
|
36
|
+
expect(asset.file_derivatives[:sample].exists?).to be(true)
|
37
|
+
|
38
|
+
# sanity check
|
39
|
+
asset.reload
|
40
|
+
expect(asset.file_derivatives[:sample]).to be_present
|
41
|
+
end
|
42
|
+
|
43
|
+
it "can avoid deleting deriv file" do
|
44
|
+
file = sample_deriv_file!
|
45
|
+
asset.file_attacher.add_persisted_derivatives({sample: file}, delete: false)
|
46
|
+
|
47
|
+
expect(File.exists?(file.path)).to eq(true)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "can use custom storage" do
|
51
|
+
file = sample_deriv_file!
|
52
|
+
asset.file_attacher.add_persisted_derivatives({sample: file}, storage: :cache)
|
53
|
+
|
54
|
+
asset.reload
|
55
|
+
expect(asset.file_derivatives[:sample]).to be_present
|
56
|
+
expect(asset.file_derivatives[:sample].storage_key).to eq(:cache)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "can supply custom metadata" do
|
60
|
+
file = sample_deriv_file!
|
61
|
+
asset.file_attacher.add_persisted_derivatives({sample: file}, metadata: { extra: "value" })
|
62
|
+
|
63
|
+
asset.reload
|
64
|
+
|
65
|
+
expect(asset.file_derivatives[:sample].metadata["extra"]).to eq("value")
|
66
|
+
# and still has default metadata
|
67
|
+
expect(asset.file_derivatives[:sample].metadata["size"]).to be_present
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "model with unsaved changes" do
|
71
|
+
before do
|
72
|
+
asset.title = "changed title"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "will refuse" do
|
76
|
+
expect {
|
77
|
+
asset.file_attacher.add_persisted_derivatives(sample: sample_deriv_file!)
|
78
|
+
}.to raise_error(TypeError)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "can be forced" do
|
82
|
+
asset.file_attacher.add_persisted_derivatives({sample: sample_deriv_file!}, allow_other_changes: true)
|
83
|
+
|
84
|
+
expect(asset.changed?).to be(false)
|
85
|
+
asset.reload
|
86
|
+
expect(asset.title).to eq("changed title")
|
87
|
+
expect(asset.file_derivatives[:sample]).to be_present
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "unsaved model" do
|
92
|
+
let(:asset) { Kithe::Asset.new(title: "test", file: File.open(sample_orig_path)) }
|
93
|
+
|
94
|
+
it "refuses even with other_changes: true" do
|
95
|
+
expect {
|
96
|
+
asset.file_attacher.add_persisted_derivatives({sample: sample_deriv_file!}, allow_other_changes: true)
|
97
|
+
}.to raise_error(TypeError)
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "with an existing derivative" do
|
101
|
+
before do
|
102
|
+
asset.save!
|
103
|
+
asset.file_attacher.add_derivative("key", StringIO.new("existing"))
|
104
|
+
asset.save!
|
105
|
+
end
|
106
|
+
|
107
|
+
it "replaces" do
|
108
|
+
existing_storage = asset.file_derivatives[:key]
|
109
|
+
expect(existing_storage.exists?).to be(true)
|
110
|
+
|
111
|
+
asset.file_attacher.add_persisted_derivatives({"key" => StringIO.new("new")})
|
112
|
+
expect(asset.file_derivatives[:key].read).to eq("new")
|
113
|
+
expect(existing_storage.exists?).to be(false)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "Original deleted before derivatives can be created" do
|
119
|
+
before do
|
120
|
+
# delete it out from under us
|
121
|
+
Kithe::Model.where(id: asset.id).delete_all
|
122
|
+
end
|
123
|
+
|
124
|
+
it "doesn't complain and cleans up file" do
|
125
|
+
|
126
|
+
# asset is no longer in the DB.
|
127
|
+
# Let's try and create derivatives for it:
|
128
|
+
file = sample_deriv_file!
|
129
|
+
local_file_path = file.path
|
130
|
+
|
131
|
+
expect(asset.file_attacher.add_persisted_derivatives(sample: file)).to be(false)
|
132
|
+
|
133
|
+
expect(File.exist?(local_file_path)).to be(false)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "Original changed before derivatives can be created" do
|
138
|
+
before do
|
139
|
+
asset # load
|
140
|
+
|
141
|
+
# Change what's in the db for this asset, without changing the in-memory
|
142
|
+
# asset
|
143
|
+
another_copy = Kithe::Asset.find(asset.id)
|
144
|
+
another_copy.file = File.open(another_sample_orig_path)
|
145
|
+
another_copy.save!
|
146
|
+
end
|
147
|
+
|
148
|
+
it "doesn't add derivative and cleans up file" do
|
149
|
+
# asset in DB has different file attachment
|
150
|
+
# Let's try and create derivatives for it:
|
151
|
+
file = sample_deriv_file!
|
152
|
+
local_file_path = file.path
|
153
|
+
|
154
|
+
expect(asset.file_attacher.add_persisted_derivatives(new_try: file)).to be(false)
|
155
|
+
|
156
|
+
|
157
|
+
expect(asset.changed?).to be(false)
|
158
|
+
expect(asset.file_derivatives[:new_try]).to be_nil
|
159
|
+
asset.reload
|
160
|
+
expect(asset.file_derivatives[:new_try]).to be_nil
|
161
|
+
|
162
|
+
expect(File.exist?(local_file_path)).to be(false)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "concurrent derivative changes" do
|
167
|
+
let(:original_one) { sample_deriv_file!(Kithe::Engine.root.join("spec/test_support/images/1x1_pixel.jpg")) }
|
168
|
+
let(:original_two) { sample_deriv_file!(Kithe::Engine.root.join("spec/test_support/images/2x2_pixel.jpg")) }
|
169
|
+
|
170
|
+
let(:new_two) { sample_deriv_file!(Kithe::Engine.root.join("spec/test_support/images/3x3_pixel.jpg")) }
|
171
|
+
let(:new_three) { sample_deriv_file!(Kithe::Engine.root.join("spec/test_support/images/3x3_pixel.jpg")) }
|
172
|
+
|
173
|
+
before do
|
174
|
+
# make sure our test is setup to test what we want
|
175
|
+
original_two.rewind; new_two.rewind
|
176
|
+
expect(original_two.read).not_to eq(new_two.read)
|
177
|
+
original_two.rewind; new_two.rewind
|
178
|
+
|
179
|
+
asset # load
|
180
|
+
|
181
|
+
# change what derivatives are in db for this asset, without changing
|
182
|
+
# the in-memory asset
|
183
|
+
another_copy = Kithe::Asset.find(asset.id)
|
184
|
+
another_copy.file_attacher.add_derivatives({
|
185
|
+
one: original_one,
|
186
|
+
two: original_two
|
187
|
+
}, delete: false)
|
188
|
+
another_copy.save!
|
189
|
+
|
190
|
+
# Make sure we set up what we expected
|
191
|
+
another_copy.reload
|
192
|
+
expect(another_copy.file_derivatives[:one]).to be_present
|
193
|
+
expect(another_copy.file_derivatives[:two]).to be_present
|
194
|
+
end
|
195
|
+
|
196
|
+
it "merges changes in safely" do
|
197
|
+
expect(asset.file_derivatives.keys).to be_empty
|
198
|
+
|
199
|
+
asset.file_attacher.add_persisted_derivatives({two: new_two, three: new_three}, delete: false)
|
200
|
+
|
201
|
+
expect(asset.changed?).to be(false)
|
202
|
+
expect(asset.file_derivatives.keys).to match([:one, :two, :three])
|
203
|
+
expect(asset.file_derivatives[:two].read).to eq(File.binread(new_two.path))
|
204
|
+
expect(asset.file_derivatives[:three].read).to eq(File.binread(new_three.path))
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "#create_persisted_derivatives" do
|
210
|
+
temporary_class("AssetSubclassUploader") do
|
211
|
+
call_fakeio = method(:fakeio) # weird closure issue
|
212
|
+
|
213
|
+
Class.new(Kithe::AssetUploader) do
|
214
|
+
self::Attacher.derivatives do |original, **options|
|
215
|
+
{
|
216
|
+
one: call_fakeio.("one"),
|
217
|
+
original_reflected: call_fakeio.(original.read)
|
218
|
+
}
|
219
|
+
end
|
220
|
+
|
221
|
+
self::Attacher.derivatives(:options) do |original, **options|
|
222
|
+
{
|
223
|
+
options_one: call_fakeio.("one"),
|
224
|
+
options_reflected: call_fakeio.(options.to_s)
|
225
|
+
}
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
temporary_class("AssetSubclass") do
|
231
|
+
Class.new(Kithe::Asset) do
|
232
|
+
set_shrine_uploader(AssetSubclassUploader)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
let(:asset) { AssetSubclass.create!(title: "test", file: File.open(sample_orig_path))}
|
237
|
+
|
238
|
+
it "creates derivatives" do
|
239
|
+
# we're not gonna test concurrency safety, counting on add_persisted_derivatives
|
240
|
+
# for that, but let's make sure
|
241
|
+
expect(asset.file_attacher).to receive(:add_persisted_derivatives).and_call_original
|
242
|
+
|
243
|
+
asset.file_attacher.create_persisted_derivatives
|
244
|
+
|
245
|
+
expect(asset.changed?).to be(false)
|
246
|
+
expect(asset.file_derivatives.keys).to match([:one, :original_reflected])
|
247
|
+
asset.reload
|
248
|
+
expect(asset.file_derivatives[:one].read).to eq("one")
|
249
|
+
expect(asset.file_derivatives[:one].storage_key).to eq(:kithe_derivatives)
|
250
|
+
expect(asset.file_derivatives[:original_reflected].read).to eq(File.binread(sample_orig_path))
|
251
|
+
expect(asset.file_derivatives[:original_reflected].storage_key).to eq(:kithe_derivatives)
|
252
|
+
end
|
253
|
+
|
254
|
+
describe "with custom source" do
|
255
|
+
let(:string_io_source) { StringIO.new("pretend data") }
|
256
|
+
|
257
|
+
it "works with custom source as StringIO" do
|
258
|
+
asset.file_attacher.create_persisted_derivatives(:options, string_io_source)
|
259
|
+
expect(asset.file_derivatives).to be_present
|
260
|
+
end
|
261
|
+
|
262
|
+
it "works with custom source StringIO as only arg" do
|
263
|
+
asset.file_attacher.create_persisted_derivatives(string_io_source)
|
264
|
+
|
265
|
+
string_io_source.rewind
|
266
|
+
expect(asset.file_derivatives[:original_reflected].read).to eq(string_io_source.read)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
describe "for an asset with nil file_data" do
|
271
|
+
let(:asset) { AssetSubclass.create!(title: "blank") }
|
272
|
+
|
273
|
+
it "no-ops" do
|
274
|
+
expect(asset.file_attacher.create_persisted_derivatives).to be(false)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe "for an asset with missing original" do
|
279
|
+
let(:asset) { AssetSubclass.create!(title: "blank", file_data: { storage: "cache", id: "not_found"}) }
|
280
|
+
|
281
|
+
it "raises" do
|
282
|
+
expect(asset.file.exists?).to be(false)
|
283
|
+
|
284
|
+
# Not necessarily what kithe 1.x did, but this seems better...
|
285
|
+
expect {
|
286
|
+
asset.file_attacher.create_persisted_derivatives
|
287
|
+
}.to raise_error(Shrine::FileNotFound)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
it "can call custom processor" do
|
292
|
+
asset.file_attacher.create_persisted_derivatives(:options)
|
293
|
+
|
294
|
+
expect(asset.file_derivatives.keys).to match([:options_one, :options_reflected])
|
295
|
+
end
|
296
|
+
|
297
|
+
it "can pass processor options" do
|
298
|
+
asset.file_attacher.create_persisted_derivatives(:options, arg1: "value1", arg2: "value2")
|
299
|
+
|
300
|
+
expect(asset.file_derivatives[:options_reflected].read).to eq({arg1: "value1", arg2: "value2"}.to_s)
|
301
|
+
end
|
302
|
+
|
303
|
+
it "can customize :storage" do
|
304
|
+
asset.file_attacher.create_persisted_derivatives(:options, storage: :cache, arg1: "value1", arg2: "value2")
|
305
|
+
|
306
|
+
expect(asset.file_derivatives[:options_reflected].read).to eq({arg1: "value1", arg2: "value2"}.to_s)
|
307
|
+
expect(asset.file_derivatives[:options_reflected].storage_key).to eq(:cache)
|
308
|
+
end
|
309
|
+
|
310
|
+
describe "model with unsaved changes" do
|
311
|
+
before do
|
312
|
+
asset.title = "changed title"
|
313
|
+
end
|
314
|
+
|
315
|
+
it "will refuse" do
|
316
|
+
expect {
|
317
|
+
asset.file_attacher.create_persisted_derivatives
|
318
|
+
}.to raise_error(TypeError)
|
319
|
+
end
|
320
|
+
|
321
|
+
it "can be forced" do
|
322
|
+
asset.file_attacher.create_persisted_derivatives(allow_other_changes: true)
|
323
|
+
|
324
|
+
expect(asset.changed?).to be(false)
|
325
|
+
asset.reload
|
326
|
+
expect(asset.title).to eq("changed title")
|
327
|
+
expect(asset.file_derivatives.keys).to match([:one, :original_reflected])
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
describe "#remove_persisted_derivatives" do
|
333
|
+
before do
|
334
|
+
asset.file_attacher.add_persisted_derivatives(
|
335
|
+
sample1: fakeio("sample 1"),
|
336
|
+
sample2: fakeio("sample 2")
|
337
|
+
)
|
338
|
+
end
|
339
|
+
|
340
|
+
it "can remove" do
|
341
|
+
removed = asset.file_attacher.remove_persisted_derivatives(:sample1)
|
342
|
+
|
343
|
+
expect(asset.changed?).to eq(false)
|
344
|
+
expect(asset.file_derivatives.keys).to eq([:sample2])
|
345
|
+
asset.reload
|
346
|
+
expect(asset.file_derivatives.keys).to eq([:sample2])
|
347
|
+
|
348
|
+
expect(removed).to be_kind_of(Array)
|
349
|
+
expect(removed.length).to eq(1)
|
350
|
+
expect(removed.first).to be_kind_of(Shrine::UploadedFile)
|
351
|
+
expect(removed.first.exists?).to be(false)
|
352
|
+
end
|
353
|
+
|
354
|
+
describe "if someone else removed first" do
|
355
|
+
before do
|
356
|
+
another_copy = asset.class.find(asset.id)
|
357
|
+
another_copy.file_attacher.remove_derivative(:sample1)
|
358
|
+
another_copy.save!
|
359
|
+
another_copy.reload
|
360
|
+
expect(another_copy.file_derivatives.keys).to eq([:sample2])
|
361
|
+
|
362
|
+
expect(asset.file_derivatives.keys).to match([:sample1, :sample2])
|
363
|
+
end
|
364
|
+
|
365
|
+
it "doesn't complain" do
|
366
|
+
asset.file_attacher.remove_persisted_derivatives(:sample1)
|
367
|
+
expect(asset.changed?).to eq(false)
|
368
|
+
expect(asset.file_derivatives.keys).to eq([:sample2])
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
describe "someone else added another derivative" do
|
373
|
+
before do
|
374
|
+
another_copy = asset.class.find(asset.id)
|
375
|
+
another_copy.file_attacher.add_persisted_derivatives({:sample3 => fakeio("sample 3")})
|
376
|
+
another_copy.reload
|
377
|
+
expect(another_copy.file_derivatives.keys).to match([:sample1, :sample2, :sample3])
|
378
|
+
|
379
|
+
expect(asset.file_derivatives.keys).to match([:sample1, :sample2])
|
380
|
+
end
|
381
|
+
|
382
|
+
it "deletes without deleting newly added" do
|
383
|
+
asset.file_attacher.remove_persisted_derivatives(:sample1)
|
384
|
+
|
385
|
+
expect(asset.changed?).to eq(false)
|
386
|
+
expect(asset.file_derivatives.keys).to eq([:sample2, :sample3])
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
describe "model deleted from under us" do
|
391
|
+
before do
|
392
|
+
another_copy = asset.class.find(asset.id)
|
393
|
+
another_copy.destroy!
|
394
|
+
end
|
395
|
+
|
396
|
+
it "silently no-ops" do
|
397
|
+
result = asset.file_attacher.remove_persisted_derivatives(:sample1)
|
398
|
+
expect(result).to eq(false)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
describe "model with unsaved changes" do
|
403
|
+
before do
|
404
|
+
asset.title = "changed title"
|
405
|
+
end
|
406
|
+
|
407
|
+
it "will refuse" do
|
408
|
+
expect {
|
409
|
+
asset.file_attacher.remove_persisted_derivatives(:sample1)
|
410
|
+
}.to raise_error(TypeError)
|
411
|
+
end
|
412
|
+
|
413
|
+
it "can be forced" do
|
414
|
+
asset.file_attacher.remove_persisted_derivatives(:sample1, allow_other_changes: true)
|
415
|
+
|
416
|
+
expect(asset.changed?).to be(false)
|
417
|
+
asset.reload
|
418
|
+
expect(asset.title).to eq("changed title")
|
419
|
+
expect(asset.file_derivatives.keys).to eq([:sample2])
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
end
|
424
|
+
end
|