delayed_paperclip 2.6.0.0 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rbenv-version +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +27 -0
  7. data/Appraisals +15 -0
  8. data/CONTRIBUTING +19 -0
  9. data/ChangeLog +4 -0
  10. data/Gemfile +11 -0
  11. data/Rakefile +7 -2
  12. data/delayed_paperclip.gemspec +26 -0
  13. data/gemfiles/paperclip3_5.gemfile +11 -0
  14. data/gemfiles/paperclip3_5.gemfile.lock +160 -0
  15. data/gemfiles/rails3.gemfile +10 -0
  16. data/gemfiles/rails3.gemfile.lock +151 -0
  17. data/gemfiles/rails3_1.gemfile +10 -0
  18. data/gemfiles/rails3_1.gemfile.lock +161 -0
  19. data/gemfiles/rails3_2.gemfile +10 -0
  20. data/gemfiles/rails3_2.gemfile.lock +159 -0
  21. data/lib/delayed_paperclip/attachment.rb +9 -7
  22. data/lib/delayed_paperclip/jobs/delayed_job.rb +2 -2
  23. data/lib/delayed_paperclip/jobs.rb +2 -2
  24. data/lib/delayed_paperclip/railtie.rb +5 -0
  25. data/lib/delayed_paperclip/url_generator.rb +15 -2
  26. data/lib/delayed_paperclip/version.rb +3 -0
  27. data/lib/delayed_paperclip.rb +28 -17
  28. data/spec/delayed_paperclip/attachment_spec.rb +153 -0
  29. data/spec/delayed_paperclip/class_methods_spec.rb +85 -0
  30. data/spec/delayed_paperclip/instance_methods_spec.rb +80 -0
  31. data/spec/delayed_paperclip/url_generator_spec.rb +171 -0
  32. data/spec/delayed_paperclip_spec.rb +56 -0
  33. data/spec/fixtures/12k.png +0 -0
  34. data/spec/integration/delayed_job_spec.rb +55 -0
  35. data/spec/integration/examples/base.rb +316 -0
  36. data/spec/integration/resque_spec.rb +40 -0
  37. data/spec/integration/sidekiq_spec.rb +48 -0
  38. data/spec/spec_helper.rb +86 -0
  39. data/test/base_delayed_paperclip_test.rb +3 -3
  40. data/test/test_helper.rb +14 -7
  41. metadata +84 -51
@@ -0,0 +1,171 @@
1
+ require 'spec_helper'
2
+
3
+ describe DelayedPaperclip::UrlGenerator do
4
+ before :all do
5
+ DelayedPaperclip.options[:background_job_class] = DelayedPaperclip::Jobs::Resque
6
+ reset_dummy
7
+ end
8
+
9
+ let(:dummy) { Dummy.create }
10
+ let(:attachment) { dummy.image }
11
+
12
+
13
+ describe "#most_appropriate_url_with_processed" do
14
+ context "without delayed_default_url" do
15
+ subject { Paperclip::UrlGenerator.new(attachment, {url: "/blah/url.jpg"})}
16
+
17
+ before :each do
18
+ subject.stubs(:delayed_default_url?).returns false
19
+ end
20
+
21
+ context "with original file name" do
22
+ before :each do
23
+ attachment.stubs(:original_filename).returns "blah"
24
+ end
25
+
26
+ it "returns options url" do
27
+ subject.most_appropriate_url_with_processed.should == "/blah/url.jpg"
28
+ end
29
+ end
30
+
31
+ context "without original_filename" do
32
+ before :each do
33
+ attachment.stubs(:original_filename).returns nil
34
+ end
35
+
36
+ context "without delayed_options" do
37
+ before :each do
38
+ attachment.stubs(:delayed_options).returns nil
39
+ end
40
+
41
+ it "gets default url" do
42
+ subject.expects(:default_url)
43
+ subject.most_appropriate_url_with_processed
44
+ end
45
+ end
46
+
47
+ context "with delayed_options" do
48
+ before :each do
49
+ attachment.stubs(:delayed_options).returns "something"
50
+ end
51
+
52
+ context "without processing_image_url" do
53
+ before :each do
54
+ attachment.stubs(:processing_image_url).returns nil
55
+ end
56
+
57
+ it "gets default url" do
58
+ subject.expects(:default_url)
59
+ subject.most_appropriate_url_with_processed
60
+ end
61
+ end
62
+
63
+ context "with processing_image_url" do
64
+ before :each do
65
+ attachment.stubs(:processing_image_url).returns "/processing/image.jpg"\
66
+ end
67
+
68
+ context "and is processing" do
69
+ before :each do
70
+ attachment.stubs(:processing?).returns true
71
+ end
72
+
73
+ it "gets processing url" do
74
+ subject.most_appropriate_url_with_processed.should == "/processing/image.jpg"
75
+ end
76
+ end
77
+
78
+ context "and is not processing" do
79
+ it "gets default url" do
80
+ subject.expects(:default_url)
81
+ subject.most_appropriate_url_with_processed
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "#timestamp_possible_with_processed?" do
91
+ subject { Paperclip::UrlGenerator.new(attachment, {})}
92
+
93
+ context "with delayed_default_url" do
94
+ before :each do
95
+ subject.stubs(:delayed_default_url?).returns true
96
+ end
97
+
98
+ it "is false" do
99
+ subject.timestamp_possible_with_processed?.should be_false
100
+ end
101
+ end
102
+
103
+ context "without delayed_default_url" do
104
+ before :each do
105
+ subject.stubs(:delayed_default_url?).returns false
106
+ end
107
+
108
+ it "goes up the chain" do
109
+ subject.expects(:timestamp_possible_without_processed?)
110
+ subject.timestamp_possible_with_processed?
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "#delayed_default_url?" do
116
+ subject { Paperclip::UrlGenerator.new(attachment, {})}
117
+
118
+ before :each do
119
+ attachment.stubs(:job_is_processing).returns false
120
+ attachment.stubs(:dirty?).returns false
121
+ attachment.delayed_options[:url_with_processing] = true
122
+ attachment.instance.stubs(:respond_to?).with(:image_processing?).returns true
123
+ attachment.stubs(:processing?).returns true
124
+ end
125
+
126
+ it "has all false, delayed_default_url returns true" do
127
+ subject.delayed_default_url?.should be_true
128
+ end
129
+
130
+ context "job is processing" do
131
+ before :each do
132
+ attachment.stubs(:job_is_processing).returns true
133
+ end
134
+
135
+ it "returns true" do
136
+ subject.delayed_default_url?.should be_false
137
+ end
138
+ end
139
+
140
+ context "attachment is dirty" do
141
+ before :each do
142
+ attachment.stubs(:dirty?).returns true
143
+ end
144
+
145
+ it "returns true" do
146
+ subject.delayed_default_url?.should be_false
147
+ end
148
+ end
149
+
150
+ context "attachment has delayed_options without url_with_processing" do
151
+ before :each do
152
+ attachment.delayed_options[:url_with_processing] = false
153
+ end
154
+
155
+ it "returns true" do
156
+ subject.delayed_default_url?.should be_false
157
+ end
158
+ end
159
+
160
+ context "attachment does not responds to name_processing and is not processing" do
161
+ before :each do
162
+ attachment.instance.stubs(:respond_to?).with(:image_processing?).returns false
163
+ attachment.stubs(:processing?).returns false
164
+ end
165
+
166
+ it "returns true" do
167
+ subject.delayed_default_url?.should be_false
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require 'resque'
3
+
4
+ describe DelayedPaperclip do
5
+ before :all do
6
+ reset_dummy
7
+ end
8
+
9
+ describe ".options" do
10
+ it ".options returns basic options" do
11
+ DelayedPaperclip.options.should == {:background_job_class => DelayedPaperclip::Jobs::Resque,
12
+ :url_with_processing => true,
13
+ :processing_image_url => nil}
14
+ end
15
+ end
16
+
17
+ describe ".processor" do
18
+ it ".processor returns processor" do
19
+ DelayedPaperclip.processor.should == DelayedPaperclip::Jobs::Resque
20
+ end
21
+ end
22
+
23
+ describe ".enqueue" do
24
+ it "delegates to processor" do
25
+ DelayedPaperclip::Jobs::Resque.expects(:enqueue_delayed_paperclip).with("Dummy", 1, :image)
26
+ DelayedPaperclip.enqueue("Dummy", 1, :image)
27
+ end
28
+ end
29
+
30
+ describe ".process_job" do
31
+ let(:dummy) { Dummy.create! }
32
+
33
+ it "finds dummy and calls #process_delayed!" do
34
+ Dummy.expects(:find).with(dummy.id).returns(dummy)
35
+ dummy.image.expects(:process_delayed!)
36
+ DelayedPaperclip.process_job("Dummy", dummy.id, :image)
37
+ end
38
+ end
39
+
40
+ describe "paperclip definitions" do
41
+ before :all do
42
+ reset_dummy :paperclip => { styles: { thumbnail: "25x25"} }
43
+ end
44
+
45
+ it "returns paperclip options regardless of version" do
46
+ Dummy.paperclip_definitions.should == {:image => { :styles => { :thumbnail => "25x25" },
47
+ :delayed => { :priority => 0,
48
+ :only_process => nil,
49
+ :url_with_processing => true,
50
+ :processing_image_url => nil}
51
+ }
52
+ }
53
+ end
54
+
55
+ end
56
+ end
Binary file
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ require 'delayed_job'
3
+
4
+ Delayed::Worker.backend = :active_record
5
+
6
+ describe "Delayed Job" do
7
+
8
+ before :all do
9
+ DelayedPaperclip.options[:background_job_class] = DelayedPaperclip::Jobs::DelayedJob
10
+ build_delayed_jobs
11
+ end
12
+
13
+ let(:dummy) { Dummy.new(:image => File.open("#{ROOT}/spec/fixtures/12k.png")) }
14
+
15
+ describe "integration tests" do
16
+ include_examples "base usage"
17
+ end
18
+
19
+ describe "perform job" do
20
+ before :each do
21
+ DelayedPaperclip.options[:url_with_processing] = true
22
+ reset_dummy
23
+ end
24
+
25
+ it "performs a job" do
26
+ dummy.image = File.open("#{ROOT}/spec/fixtures/12k.png")
27
+ Paperclip::Attachment.any_instance.expects(:reprocess!)
28
+ dummy.save!
29
+ Delayed::Job.last.payload_object.perform
30
+ end
31
+ end
32
+
33
+ def process_jobs
34
+ Delayed::Worker.new.work_off
35
+ end
36
+
37
+ def jobs_count
38
+ Delayed::Job.count
39
+ end
40
+
41
+ def build_delayed_jobs
42
+ ActiveRecord::Base.connection.create_table :delayed_jobs, :force => true do |table|
43
+ table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
44
+ table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
45
+ table.text :handler # YAML-encoded string of the object that will do work
46
+ table.string :last_error # reason for last failure (See Note below)
47
+ table.datetime :run_at # When to run. Could be Time.now for immediately, or sometime in the future.
48
+ table.datetime :locked_at # Set when a client is working on this object
49
+ table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
50
+ table.string :locked_by # Who is working on this object (if locked)
51
+ table.string :queue
52
+ table.timestamps
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,316 @@
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_false
16
+ dummy.image.post_processing.should be_true
17
+ dummy.save.should be_true
18
+ File.exists?(dummy.image.path).should be_true
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_false
56
+ end
57
+
58
+ it "post processing returns true" do
59
+ dummy.image.post_processing.should be_true
60
+ end
61
+
62
+ it "writes the file" do
63
+ dummy.save
64
+ File.exists?(dummy.image.path).should be_true
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_true
77
+ end
78
+
79
+ it "post_processing is false" do
80
+ dummy.image.post_processing.should be_false
81
+ end
82
+
83
+ it "has file after save" do
84
+ dummy.save
85
+ File.exists?(dummy.image.path).should be_true
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_true
102
+ process_jobs
103
+ dummy.reload.image_processing?.should be_false
104
+ end
105
+
106
+ context "with error" do
107
+ before :each do
108
+ Paperclip::Attachment.any_instance.stubs(:reprocess!).raises(StandardError.new('oops'))
109
+ end
110
+
111
+ it "stays true even if errored" do
112
+ dummy.save!
113
+ dummy.image_processing?.should be_true
114
+ process_jobs
115
+ dummy.image_processing?.should be_true
116
+ dummy.reload.image_processing?.should be_true
117
+ end
118
+ end
119
+ end
120
+
121
+ # TODO: test appears redundant
122
+ describe "processing is true for new record" do
123
+ it "is true" do
124
+ dummy.image_processing?.should be_false
125
+ dummy.new_record?.should be_true
126
+ dummy.save!
127
+ dummy.reload.image_processing?.should be_true
128
+ end
129
+ end
130
+
131
+ describe "urls" do
132
+ it "returns missing url until job is finished" do
133
+ dummy.save!
134
+ dummy.image.url.should start_with("/images/original/missing.png")
135
+ process_jobs
136
+ dummy.reload
137
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
138
+ end
139
+
140
+ context "processing url" do
141
+ before :each do
142
+ reset_dummy :processing_image_url => "/images/original/processing.png"
143
+ end
144
+
145
+ it "returns processing url while processing" do
146
+ dummy.save!
147
+ dummy.image.url.should start_with("/images/original/processing.png")
148
+ process_jobs
149
+ dummy.reload
150
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
151
+ end
152
+
153
+ context "defaults to missing when no file" do
154
+ it "fallsback gracefully" do
155
+ dummy = Dummy.new()
156
+ dummy.save!
157
+ dummy.reload.image.url.should start_with("/images/original/missing.png")
158
+ end
159
+ end
160
+ end
161
+
162
+ context "same url if same file assigned" do
163
+ it "falls to missing while processing" do
164
+ dummy.save!
165
+ dummy.image = File.open("#{ROOT}/spec/fixtures/12k.png")
166
+ dummy.save!
167
+ dummy.image.url.should start_with("/images/original/missing.png")
168
+ process_jobs
169
+ dummy.reload.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+ describe "callbacks" do
176
+ context "paperclip callback" do
177
+ before :each do
178
+ Dummy.send(:define_method, :done_processing) { puts 'done' }
179
+ Dummy.after_image_post_process :done_processing
180
+ Dummy.any_instance.expects(:done_processing).once
181
+ end
182
+
183
+ it "observes after_image_post_process" do
184
+ dummy.save!
185
+ process_jobs
186
+ end
187
+ end
188
+
189
+ context "after_update callback" do
190
+ before :each do
191
+ reset_class "Dummy", :with_processed => true,
192
+ :with_after_update_callback => true
193
+ end
194
+
195
+ it "hits after_update" do
196
+ Dummy.any_instance.expects(:reprocess).once
197
+ dummy.save!
198
+ process_jobs
199
+ end
200
+ end
201
+ end
202
+
203
+ describe "only_process option" do
204
+
205
+ # TODO: This test must be faulty
206
+ # https://github.com/jrgifford/delayed_paperclip/issues/40
207
+ context "passed just to delayed_paperclip argument" do
208
+ before :each do
209
+ reset_class "Dummy", :with_processed => true, :only_process => [:thumbnail]
210
+ end
211
+
212
+ it "reprocesses just those" do
213
+ Paperclip::Attachment.any_instance.expects(:reprocess!).with(:thumbnail).once
214
+ dummy.save!
215
+ process_jobs
216
+ end
217
+ end
218
+
219
+ context "inherits from paperclip options" do
220
+ before :each do
221
+ reset_class "Dummy", :with_processed => true, :paperclip => { :only_process => [:thumbnail] }
222
+ end
223
+
224
+ it "reprocesses just those" do
225
+ Paperclip::Attachment.any_instance.expects(:reprocess!).with(:thumbnail).once
226
+ dummy.save!
227
+ process_jobs
228
+ end
229
+ end
230
+ end
231
+
232
+ describe "converts image formats" do
233
+ before :each do
234
+ reset_class "Dummy", :with_processed => true,
235
+ :paperclip => {
236
+ :styles => {
237
+ :thumbnail => ['12x12', :jpg]
238
+ }
239
+ }
240
+ end
241
+
242
+ it "observes the option" do
243
+ dummy.save!
244
+ process_jobs
245
+ dummy.reload.image.url(:thumbnail).should start_with("/system/dummies/images/000/000/001/thumbnail/12k.jpg")
246
+ File.exists?(dummy.image.path).should be_true
247
+ end
248
+ end
249
+
250
+ describe "reprocess_without_delay" do
251
+ before :each do
252
+ DelayedPaperclip.options[:url_with_processing] = true
253
+ reset_dummy :paperclip => {
254
+ :styles => {
255
+ :thumbnail => '12x12'
256
+ }
257
+ }
258
+ end
259
+
260
+ it "does not increase jobs count" do
261
+ dummy.save!
262
+ dummy.image_processing?.should be_true
263
+ process_jobs
264
+ dummy.reload.image_processing?.should be_false
265
+
266
+ Paperclip::Attachment.any_instance.expects(:reprocess!).once
267
+
268
+ existing_jobs = jobs_count
269
+ dummy.image.reprocess_without_delay!(:thumbnail)
270
+ existing_jobs.should == jobs_count
271
+
272
+ dummy.image_processing?.should be_false
273
+ File.exists?(dummy.image.path).should be_true
274
+ end
275
+
276
+ end
277
+
278
+ describe "reprocessing_url" do
279
+
280
+ context "interpolation of styles" do
281
+ before :each do
282
+ reset_dummy :processing_image_url => "/images/:style/processing.png",
283
+ :paperclip => {
284
+ :styles => {
285
+ :thumbnail => '12x12'
286
+ }
287
+ }
288
+ end
289
+
290
+ it "interpolates unporcessed image" do
291
+ dummy.save!
292
+ dummy.image.url.should start_with("/images/original/processing.png")
293
+ dummy.image.url(:thumbnail).should start_with("/images/thumbnail/processing.png")
294
+ process_jobs
295
+ dummy.reload.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
296
+ end
297
+ end
298
+
299
+ context "proc for reprocessing_url" do
300
+ before :each do
301
+ reset_dummy :processing_image_url => lambda { |attachment| attachment.instance.reprocessing_url }
302
+ Dummy.send(:define_method, :reprocessing_url) { 'done' }
303
+ end
304
+
305
+ it "calls it correctly" do
306
+ dummy.save!
307
+ dummy.image.url.should start_with("done")
308
+ process_jobs
309
+ dummy.reload
310
+ dummy.image.url.should start_with("/system/dummies/images/000/000/001/original/12k.png")
311
+ end
312
+ end
313
+ end
314
+
315
+ end
316
+
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'resque'
3
+
4
+ describe "Resque" do
5
+
6
+ before :all do
7
+ DelayedPaperclip.options[:background_job_class] = DelayedPaperclip::Jobs::Resque
8
+ Resque.remove_queue(:paperclip)
9
+ end
10
+
11
+ let(:dummy) { Dummy.new(:image => File.open("#{ROOT}/spec/fixtures/12k.png")) }
12
+
13
+ describe "integration tests" do
14
+ include_examples "base usage"
15
+ end
16
+
17
+ describe "perform job" do
18
+ before :each do
19
+ DelayedPaperclip.options[:url_with_processing] = true
20
+ reset_dummy
21
+ end
22
+
23
+ it "performs a job" do
24
+ dummy.image = File.open("#{ROOT}/spec/fixtures/12k.png")
25
+ Paperclip::Attachment.any_instance.expects(:reprocess!)
26
+ dummy.save!
27
+ DelayedPaperclip::Jobs::Resque.perform(dummy.class.name, dummy.id, :image)
28
+ end
29
+ end
30
+
31
+ def process_jobs
32
+ worker = Resque::Worker.new(:paperclip)
33
+ worker.process
34
+ end
35
+
36
+ def jobs_count
37
+ Resque.size(:paperclip)
38
+ end
39
+
40
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'sidekiq'
3
+
4
+ describe "Sidekiq" do
5
+
6
+ before :all do
7
+ Sidekiq.logger.level = Logger::ERROR
8
+ DelayedPaperclip.options[:background_job_class] = DelayedPaperclip::Jobs::Sidekiq
9
+ Sidekiq::Queue.new(:paperclip).clear
10
+ end
11
+
12
+ let(:dummy) { Dummy.new(:image => File.open("#{ROOT}/spec/fixtures/12k.png")) }
13
+
14
+ describe "integration tests" do
15
+ include_examples "base usage"
16
+ end
17
+
18
+ describe "perform job" do
19
+ before :each do
20
+ DelayedPaperclip.options[:url_with_processing] = true
21
+ reset_dummy
22
+ end
23
+
24
+ it "performs a job" do
25
+ dummy.image = File.open("#{ROOT}/spec/fixtures/12k.png")
26
+ Paperclip::Attachment.any_instance.expects(:reprocess!)
27
+ dummy.save!
28
+ DelayedPaperclip::Jobs::Sidekiq.new.perform(dummy.class.name, dummy.id, :image)
29
+ end
30
+ end
31
+
32
+ def process_jobs
33
+ Sidekiq::Queue.new(:paperclip).each do |job|
34
+ worker = job.klass.constantize.new
35
+ args = job.args
36
+ begin
37
+ worker.perform(*args)
38
+ rescue # Assume sidekiq handle exception properly
39
+ end
40
+ job.delete
41
+ end
42
+ end
43
+
44
+ def jobs_count
45
+ Sidekiq::Queue.new(:paperclip).size
46
+ end
47
+
48
+ end