kt-delayed_paperclip 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Binary file
Binary file
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Base Delayed Paperclip Integration" do
4
+ let(:dummy) { Dummy.create }
5
+
6
+ before :each do
7
+ reset_dummy(paperclip: { default_url: "/../../fixtures/missing.png" })
8
+ end
9
+
10
+ describe "double save" do
11
+ before :each do
12
+ dummy.image_processing.should be_falsey
13
+ dummy.image = File.open("#{ROOT}/fixtures/12k.png")
14
+ dummy.save!
15
+ end
16
+
17
+ it "processing column remains true" do
18
+ dummy.image_processing.should be_truthy
19
+ dummy.save!
20
+ dummy.image_processing.should be_truthy
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,326 @@
1
+ shared_examples "base usage" do
2
+ before :each do
3
+ DelayedPaperclip.options[:url_with_processing] = true
4
+ reset_dummy
5
+ end
6
+
7
+ describe "normal paperclip" do
8
+ before :each do
9
+ DelayedPaperclip.options[:url_with_processing] = false
10
+ reset_dummy :with_processed => false
11
+ end
12
+
13
+ it "allows normal paperclip functionality" do
14
+ Paperclip::Attachment.any_instance.expects(:post_process)
15
+ dummy.image.delay_processing?.should be_falsey
16
+ dummy.image.post_processing.should be_truthy
17
+ dummy.save.should be_truthy
18
+ File.exists?(dummy.image.path).should be_truthy
19
+ end
20
+
21
+ context "missing url" do
22
+ it "does not return missing url if false globally" do
23
+ dummy.save!
24
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
25
+ process_jobs
26
+ dummy.reload
27
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
28
+ end
29
+
30
+ it "does not return missing url if false on instance" do
31
+ reset_dummy :with_processed => false, :url_with_processing => false
32
+ dummy.save!
33
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
34
+ process_jobs # There aren't any
35
+ dummy.reload
36
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
37
+ end
38
+ end
39
+
40
+ # TODO: somewhat duplicate test of the above
41
+ context "original url without processing column" do
42
+ it "works normally" do
43
+ dummy.save!
44
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "set post processing" do
50
+ before :each do
51
+ reset_dummy :with_processed => true
52
+ dummy.image.post_processing = true
53
+ end
54
+ it "has delay_processing is false" do
55
+ dummy.image.delay_processing?.should be_falsey
56
+ end
57
+
58
+ it "post processing returns true" do
59
+ dummy.image.post_processing.should be_truthy
60
+ end
61
+
62
+ it "writes the file" do
63
+ dummy.save
64
+ File.exists?(dummy.image.path).should be_truthy
65
+ end
66
+ end
67
+
68
+ describe "without processing column" do
69
+ before :each do
70
+ build_dummy_table(false)
71
+ reset_class "Dummy", :with_processed => true
72
+ Paperclip::Attachment.any_instance.expects(:post_process).never
73
+ end
74
+
75
+ it "delays processing" do
76
+ dummy.image.delay_processing?.should be_truthy
77
+ end
78
+
79
+ it "post_processing is false" do
80
+ dummy.image.post_processing.should be_falsey
81
+ end
82
+
83
+ it "has file after save" do
84
+ dummy.save
85
+ File.exists?(dummy.image.path).should be_truthy
86
+ end
87
+
88
+ end
89
+
90
+ describe "jobs count" do
91
+ it "increments by 1" do
92
+ original_job_count = jobs_count
93
+ dummy.save
94
+ jobs_count.should == original_job_count + 1
95
+ end
96
+ end
97
+
98
+ describe "processing column not altered" do
99
+ it "resets after job finished" do
100
+ dummy.save!
101
+ dummy.image_processing?.should be_truthy
102
+ process_jobs
103
+ dummy.reload.image_processing?.should be_falsey
104
+ end
105
+
106
+ context "with error" do
107
+ it "stays true even if errored" do
108
+ Paperclip::Attachment.any_instance.stubs(:reprocess!).raises(StandardError.new('oops'))
109
+
110
+ dummy.save!
111
+ dummy.image_processing?.should be_truthy
112
+
113
+ expect do
114
+ process_jobs
115
+ end.to raise_error(StandardError)
116
+
117
+ dummy.image_processing?.should be_truthy
118
+ dummy.reload.image_processing?.should be_truthy
119
+ end
120
+ end
121
+ end
122
+
123
+ # TODO: test appears redundant
124
+ describe "processing is true for new record" do
125
+ it "is true" do
126
+ dummy.image_processing?.should be_falsey
127
+ dummy.new_record?.should be_truthy
128
+ dummy.save!
129
+ dummy.reload.image_processing?.should be_truthy
130
+ end
131
+ end
132
+
133
+ describe "urls" do
134
+ it "returns missing url until job is finished" do
135
+ dummy.save!
136
+ dummy.image.url.should start_with("/images/original/missing.png")
137
+ process_jobs
138
+ dummy.reload
139
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
140
+ end
141
+
142
+ context "processing url" do
143
+ before :each do
144
+ reset_dummy :processing_image_url => "/images/original/processing.png"
145
+ end
146
+
147
+ it "returns processing url while processing" do
148
+ dummy.save!
149
+ dummy.image.url.should start_with("/images/original/processing.png")
150
+ process_jobs
151
+ dummy.reload
152
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
153
+ end
154
+
155
+ context "defaults to missing when no file" do
156
+ it "fallsback gracefully" do
157
+ dummy = Dummy.new()
158
+ dummy.save!
159
+ dummy.reload.image.url.should start_with("/images/original/missing.png")
160
+ end
161
+ end
162
+ end
163
+
164
+ context "same url if same file assigned" do
165
+ it "falls to missing while processing" do
166
+ dummy.save!
167
+ dummy.image = File.open("#{ROOT}/fixtures/12k.png")
168
+ dummy.save!
169
+ dummy.image.url.should start_with("/images/original/missing.png")
170
+ process_jobs
171
+ dummy.reload.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
172
+ end
173
+ end
174
+
175
+ end
176
+
177
+ describe "callbacks" do
178
+ context "paperclip callback" do
179
+ before :each do
180
+ Dummy.send(:define_method, :done_processing) { puts 'done' }
181
+ Dummy.send(:after_image_post_process, :done_processing)
182
+ Dummy.any_instance.expects(:done_processing).once
183
+ end
184
+
185
+ it "observes after_image_post_process" do
186
+ dummy.save!
187
+ process_jobs
188
+ end
189
+ end
190
+
191
+ context "after_update callback" do
192
+ before :each do
193
+ reset_class "Dummy", :with_processed => true,
194
+ :with_after_update_callback => true
195
+ end
196
+
197
+ it "hits after_update" do
198
+ Dummy.any_instance.expects(:reprocess).once
199
+ dummy.save!
200
+ process_jobs
201
+ end
202
+ end
203
+ end
204
+
205
+ describe "only_process option" do
206
+
207
+ # TODO: This test must be faulty
208
+ # https://github.com/jrgifford/delayed_paperclip/issues/40
209
+ context "passed just to delayed_paperclip argument" do
210
+ before :each do
211
+ reset_class "Dummy", :with_processed => true, :only_process => [:thumbnail]
212
+ end
213
+
214
+ it "reprocesses just those" do
215
+ Paperclip::Attachment.any_instance.expects(:reprocess!).with(:thumbnail).once
216
+ dummy.save!
217
+ process_jobs
218
+ end
219
+ end
220
+
221
+ context "inherits from paperclip options" do
222
+ before :each do
223
+ reset_class "Dummy", :with_processed => true, :paperclip => { :only_process => [:thumbnail] }
224
+ end
225
+
226
+ it "reprocesses just those" do
227
+ Paperclip::Attachment.any_instance.expects(:reprocess!).with(:thumbnail).once
228
+ dummy.save!
229
+ process_jobs
230
+ end
231
+ end
232
+ end
233
+
234
+ describe "converts image formats" do
235
+ before :each do
236
+ reset_class "Dummy", :with_processed => true,
237
+ :paperclip => {
238
+ :styles => {
239
+ :thumbnail => ['12x12', :jpg]
240
+ }
241
+ }
242
+ end
243
+
244
+ it "observes the option" do
245
+ dummy.save!
246
+ process_jobs
247
+ dummy.reload.image.url(:thumbnail).should start_with("/system/dummies/images/000/000/001/thumbnail/12k.jpg")
248
+ File.exists?(dummy.image.path).should be_truthy
249
+ end
250
+ end
251
+
252
+ describe "reprocess_without_delay" do
253
+ before :each do
254
+ DelayedPaperclip.options[:url_with_processing] = true
255
+ reset_dummy :paperclip => {
256
+ :styles => {
257
+ :thumbnail => '12x12'
258
+ }
259
+ }
260
+ end
261
+
262
+ it "does not increase jobs count" do
263
+ dummy.save!
264
+ dummy.image_processing?.should be_truthy
265
+ process_jobs
266
+ dummy.reload.image_processing?.should be_falsey
267
+
268
+ Paperclip::Attachment.any_instance.expects(:reprocess!).once
269
+
270
+ existing_jobs = jobs_count
271
+ dummy.image.reprocess_without_delay!(:thumbnail)
272
+ existing_jobs.should == jobs_count
273
+
274
+ dummy.image_processing?.should be_falsey
275
+ File.exists?(dummy.image.path).should be_truthy
276
+ end
277
+
278
+ end
279
+
280
+ describe "reprocessing_url" do
281
+
282
+ context "interpolation of styles" do
283
+ before :each do
284
+ reset_dummy :processing_image_url => "/images/:style/processing.png",
285
+ :paperclip => {
286
+ :styles => {
287
+ :thumbnail => '12x12'
288
+ }
289
+ }
290
+ end
291
+
292
+ it "interpolates unporcessed image" do
293
+ dummy.save!
294
+ dummy.image.url.should start_with("/images/original/processing.png")
295
+ dummy.image.url(:thumbnail).should start_with("/images/thumbnail/processing.png")
296
+ process_jobs
297
+ dummy.reload.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
298
+ end
299
+ end
300
+
301
+ context "proc for reprocessing_url" do
302
+ before :each do
303
+ reset_dummy :processing_image_url => lambda { |attachment| attachment.instance.reprocessing_url }
304
+ Dummy.send(:define_method, :reprocessing_url) { 'done' }
305
+ end
306
+
307
+ it "calls it correctly" do
308
+ dummy.save!
309
+ dummy.image.url.should start_with("done")
310
+ process_jobs
311
+ dummy.reload
312
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
313
+ end
314
+ end
315
+ end
316
+
317
+ describe "queue option" do
318
+ it "enqueues job with given queue name" do
319
+ reset_dummy :queue => "custom"
320
+
321
+ expect do
322
+ dummy.save!
323
+ end.to change { jobs_count("custom") }.by(1)
324
+ end
325
+ end
326
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "DelayedJob::ProcessJob" do
4
+ before :each do
5
+ ActiveJob::Base.queue_adapter = :test
6
+ ActiveJob::Base.logger = nil
7
+ end
8
+
9
+ let(:dummy) { Dummy.new(:image => File.open("#{ROOT}/fixtures/12k.png")) }
10
+
11
+ describe "integration tests" do
12
+ include_examples "base usage"
13
+ end
14
+
15
+ def process_jobs
16
+ ActiveJob::Base.queue_adapter.enqueued_jobs.each do |job|
17
+ job[:job].send(:perform_now, *job[:args])
18
+ end
19
+ end
20
+
21
+ def jobs_count(queue = "paperclip")
22
+ ActiveJob::Base.queue_adapter.enqueued_jobs.count do |job|
23
+ job[:queue] == queue
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,122 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
3
+
4
+ require 'rails'
5
+ require 'active_record'
6
+ require 'rspec'
7
+ require 'mocha/api'
8
+
9
+ begin
10
+ require 'pry'
11
+ rescue LoadError
12
+ # Pry is not available, just ignore.
13
+ end
14
+
15
+ require 'paperclip/railtie'
16
+ Paperclip::Railtie.insert
17
+
18
+ require 'delayed_paperclip/railtie'
19
+ DelayedPaperclip::Railtie.insert
20
+
21
+ # silence deprecation warnings in rails 4.2
22
+ # in Rails 5 this setting is deprecated and has no effect
23
+ if ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks=) && Rails::VERSION::MAJOR < 5
24
+ ActiveRecord::Base.raise_in_transactional_callbacks = true
25
+ end
26
+
27
+ # Connect to sqlite
28
+ ActiveRecord::Base.establish_connection(
29
+ "adapter" => "sqlite3",
30
+ "database" => ":memory:"
31
+ )
32
+
33
+ # Path for filesystem writing
34
+ ROOT = Pathname.new(File.expand_path("../.", __FILE__))
35
+
36
+ logger = Logger.new(ROOT.join("tmp/debug.log"))
37
+ ActiveRecord::Base.logger = logger
38
+ ActiveJob::Base.logger = logger
39
+ Paperclip.logger = logger
40
+
41
+ RSpec.configure do |config|
42
+ config.mock_with :mocha
43
+
44
+ config.order = :random
45
+
46
+ config.filter_run focus: true
47
+ config.run_all_when_everything_filtered = true
48
+
49
+ config.before(:each) do
50
+ reset_global_default_options
51
+ end
52
+ end
53
+
54
+ def reset_global_default_options
55
+ DelayedPaperclip.options.merge!({
56
+ :background_job_class => DelayedPaperclip::ProcessJob,
57
+ :url_with_processing => true,
58
+ :processing_image_url => nil
59
+ })
60
+ end
61
+
62
+ # In order to not duplicate code directly from Paperclip's spec support
63
+ # We're requiring the MockInterpolator object to be used
64
+ require Gem.find_files("../spec/support/mock_interpolator").first
65
+
66
+ Dir["./spec/integration/examples/*.rb"].sort.each { |f| require f }
67
+
68
+ # Reset table and class with image_processing column or not
69
+ def reset_dummy(options = {})
70
+ options[:with_processed] = true unless options.key?(:with_processed)
71
+ options[:processed_column] = options[:with_processed] unless options.has_key?(:processed_column)
72
+
73
+ build_dummy_table(options.delete(:processed_column))
74
+ reset_class("Dummy", options)
75
+ end
76
+
77
+ # Dummy Table for images
78
+ # with or without image_processing column
79
+ def build_dummy_table(with_column)
80
+ ActiveRecord::Base.connection.create_table :dummies, :force => true do |t|
81
+ t.string :name
82
+ t.string :image_file_name
83
+ t.string :image_content_type
84
+ t.integer :image_file_size
85
+ t.datetime :image_updated_at
86
+ t.boolean :hidden, :default => false
87
+ t.boolean(:image_processing, :default => false) if with_column
88
+ end
89
+ end
90
+
91
+ def reset_class(class_name, options)
92
+ # setup class and include paperclip
93
+ options[:paperclip] = {} if options[:paperclip].nil?
94
+ ActiveRecord::Base.send(:include, Paperclip::Glue)
95
+ Object.send(:remove_const, class_name) rescue nil
96
+
97
+ # Set class as a constant
98
+ klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
99
+
100
+ # Setup class with paperclip and delayed paperclip
101
+ klass.class_eval do
102
+ include Paperclip::Glue
103
+
104
+ has_attached_file :image, options.delete(:paperclip)
105
+
106
+ validates_attachment :image, :content_type => { :content_type => "image/png" }
107
+
108
+ process_in_background :image, options if options[:with_processed]
109
+
110
+ after_update :reprocess if options[:with_after_update_callback]
111
+
112
+ default_scope options[:default_scope] if options[:default_scope]
113
+
114
+ def reprocess
115
+ image.reprocess!
116
+ end
117
+ end
118
+
119
+ Rails.stubs(:root).returns(ROOT.join("tmp"))
120
+ klass.reset_column_information
121
+ klass
122
+ end