kt-delayed_paperclip 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +36 -0
- data/Appraisals +12 -0
- data/CONTRIBUTING +16 -0
- data/ChangeLog +1 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +314 -0
- data/Rakefile +20 -0
- data/delayed_paperclip.gemspec +30 -0
- data/gemfiles/.bundle/config +1 -0
- data/gemfiles/4.2.gemfile +7 -0
- data/gemfiles/5.0.gemfile +7 -0
- data/gemfiles/5.0_paperclip_master.gemfile +8 -0
- data/lib/delayed_paperclip.rb +119 -0
- data/lib/delayed_paperclip/attachment.rb +89 -0
- data/lib/delayed_paperclip/process_job.rb +14 -0
- data/lib/delayed_paperclip/railtie.rb +27 -0
- data/lib/delayed_paperclip/url_generator.rb +61 -0
- data/lib/delayed_paperclip/version.rb +3 -0
- data/lib/kt-delayed_paperclip.rb +2 -0
- data/spec/delayed_paperclip/attachment_spec.rb +345 -0
- data/spec/delayed_paperclip/class_methods_spec.rb +95 -0
- data/spec/delayed_paperclip/instance_methods_spec.rb +71 -0
- data/spec/delayed_paperclip/url_generator_spec.rb +273 -0
- data/spec/delayed_paperclip_spec.rb +66 -0
- data/spec/fixtures/12k.png +0 -0
- data/spec/fixtures/missing.png +0 -0
- data/spec/integration/base_delayed_paperclip_spec.rb +23 -0
- data/spec/integration/examples/base.rb +326 -0
- data/spec/integration/process_job_spec.rb +26 -0
- data/spec/spec_helper.rb +122 -0
- data/spec/tmp/.keep +0 -0
- metadata +238 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "delayed_paperclip/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = %q{kt-delayed_paperclip}
|
6
|
+
s.version = DelayedPaperclip::VERSION
|
7
|
+
|
8
|
+
s.authors = ["Adam Anderson", "Jesse Storimer", "Bert Goethals", "James Gifford", "Scott Carleton"]
|
9
|
+
s.summary = %q{Process your Paperclip attachments in the background}
|
10
|
+
s.description = %q{Process your Paperclip attachments in the background with ActiveJob}
|
11
|
+
s.email = %w{james@jamesrgifford.com scott@artsicle.com}
|
12
|
+
s.homepage = %q{https://github.com/adamtao/kt-delayed_paperclip}
|
13
|
+
|
14
|
+
s.required_ruby_version = ">= 2.0.0"
|
15
|
+
|
16
|
+
s.add_dependency 'kt-paperclip', "~> 6.4", ">= 6.4.1"
|
17
|
+
s.add_dependency 'activejob', ">= 4.2"
|
18
|
+
|
19
|
+
s.add_development_dependency 'mocha'
|
20
|
+
s.add_development_dependency "rspec", '< 3.0'
|
21
|
+
s.add_development_dependency 'sqlite3'
|
22
|
+
s.add_development_dependency 'appraisal'
|
23
|
+
s.add_development_dependency 'rake', '~> 10.5.0'
|
24
|
+
s.add_development_dependency 'bundler'
|
25
|
+
s.add_development_dependency 'activerecord'
|
26
|
+
s.add_development_dependency 'railties'
|
27
|
+
|
28
|
+
s.files = `git ls-files`.split("\n")
|
29
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
30
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
--- {}
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'kt-paperclip'
|
2
|
+
require 'delayed_paperclip/process_job'
|
3
|
+
require 'delayed_paperclip/attachment'
|
4
|
+
require 'delayed_paperclip/url_generator'
|
5
|
+
require 'delayed_paperclip/railtie' if defined?(Rails)
|
6
|
+
|
7
|
+
module DelayedPaperclip
|
8
|
+
class << self
|
9
|
+
def options
|
10
|
+
@options ||= {
|
11
|
+
:background_job_class => DelayedPaperclip::ProcessJob,
|
12
|
+
:url_with_processing => true,
|
13
|
+
:processing_image_url => nil,
|
14
|
+
:queue => "paperclip"
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def processor
|
19
|
+
options[:background_job_class]
|
20
|
+
end
|
21
|
+
|
22
|
+
def enqueue(instance_klass, instance_id, attachment_name)
|
23
|
+
processor.enqueue_delayed_paperclip(instance_klass, instance_id, attachment_name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def process_job(instance_klass, instance_id, attachment_name)
|
27
|
+
instance = instance_klass.constantize.unscoped.where(id: instance_id).first
|
28
|
+
return if instance.blank?
|
29
|
+
|
30
|
+
instance.
|
31
|
+
send(attachment_name).
|
32
|
+
process_delayed!
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
module Glue
|
38
|
+
def self.included(base)
|
39
|
+
base.extend(ClassMethods)
|
40
|
+
base.send :include, InstanceMethods
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module ClassMethods
|
45
|
+
|
46
|
+
def process_in_background(name, options = {})
|
47
|
+
# initialize as hash
|
48
|
+
paperclip_definitions[name][:delayed] = {}
|
49
|
+
|
50
|
+
# Set Defaults
|
51
|
+
only_process_default = paperclip_definitions[name][:only_process]
|
52
|
+
only_process_default ||= []
|
53
|
+
{
|
54
|
+
:priority => 0,
|
55
|
+
:only_process => only_process_default,
|
56
|
+
:url_with_processing => DelayedPaperclip.options[:url_with_processing],
|
57
|
+
:processing_image_url => DelayedPaperclip.options[:processing_image_url],
|
58
|
+
:queue => DelayedPaperclip.options[:queue]
|
59
|
+
}.each do |option, default|
|
60
|
+
paperclip_definitions[name][:delayed][option] = options.key?(option) ? options[option] : default
|
61
|
+
end
|
62
|
+
|
63
|
+
# Sets callback
|
64
|
+
if respond_to?(:after_commit)
|
65
|
+
after_commit :enqueue_delayed_processing
|
66
|
+
else
|
67
|
+
after_save :enqueue_delayed_processing
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def paperclip_definitions
|
72
|
+
if respond_to? :attachment_definitions
|
73
|
+
attachment_definitions
|
74
|
+
else
|
75
|
+
Paperclip::Tasks::Attachments.definitions_for(self)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
module InstanceMethods
|
81
|
+
|
82
|
+
# First mark processing
|
83
|
+
# then enqueue
|
84
|
+
def enqueue_delayed_processing
|
85
|
+
mark_enqueue_delayed_processing
|
86
|
+
|
87
|
+
(@_enqued_for_processing || []).each do |name|
|
88
|
+
enqueue_post_processing_for(name)
|
89
|
+
end
|
90
|
+
@_enqued_for_processing_with_processing = []
|
91
|
+
@_enqued_for_processing = []
|
92
|
+
end
|
93
|
+
|
94
|
+
# setting each inididual NAME_processing to true, skipping the ActiveModel dirty setter
|
95
|
+
# Then immediately push the state to the database
|
96
|
+
def mark_enqueue_delayed_processing
|
97
|
+
unless @_enqued_for_processing_with_processing.blank? # catches nil and empty arrays
|
98
|
+
updates = @_enqued_for_processing_with_processing.collect{|n| "#{n}_processing = :true" }.join(", ")
|
99
|
+
updates = ActiveRecord::Base.send(:sanitize_sql_array, [updates, {:true => true}])
|
100
|
+
self.class.unscoped.where(:id => self.id).update_all(updates)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def enqueue_post_processing_for name
|
105
|
+
DelayedPaperclip.enqueue(self.class.name, read_attribute(:id), name.to_sym)
|
106
|
+
end
|
107
|
+
|
108
|
+
def prepare_enqueueing_for name
|
109
|
+
if self.attributes.has_key? "#{name}_processing"
|
110
|
+
write_attribute("#{name}_processing", true)
|
111
|
+
@_enqued_for_processing_with_processing ||= []
|
112
|
+
@_enqued_for_processing_with_processing << name
|
113
|
+
end
|
114
|
+
|
115
|
+
@_enqued_for_processing ||= []
|
116
|
+
@_enqued_for_processing << name
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module DelayedPaperclip
|
2
|
+
module Attachment
|
3
|
+
attr_accessor :job_is_processing
|
4
|
+
|
5
|
+
def delayed_options
|
6
|
+
options[:delayed]
|
7
|
+
end
|
8
|
+
|
9
|
+
# Attr accessor in Paperclip
|
10
|
+
def post_processing
|
11
|
+
!delay_processing? || split_processing?
|
12
|
+
end
|
13
|
+
|
14
|
+
def post_processing=(value)
|
15
|
+
@post_processing_with_delay = value
|
16
|
+
end
|
17
|
+
|
18
|
+
# if nil, returns whether it has delayed options
|
19
|
+
# if set, then it returns
|
20
|
+
def delay_processing?
|
21
|
+
if @post_processing_with_delay.nil?
|
22
|
+
!!delayed_options
|
23
|
+
else
|
24
|
+
!@post_processing_with_delay
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def split_processing?
|
29
|
+
options[:only_process] && delayed_options &&
|
30
|
+
options[:only_process] != delayed_only_process
|
31
|
+
end
|
32
|
+
|
33
|
+
def processing?
|
34
|
+
column_name = :"#{@name}_processing?"
|
35
|
+
@instance.respond_to?(column_name) && @instance.send(column_name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def processing_style?(style)
|
39
|
+
return false if !processing?
|
40
|
+
|
41
|
+
!split_processing? || delayed_only_process.include?(style)
|
42
|
+
end
|
43
|
+
|
44
|
+
def delayed_only_process
|
45
|
+
only_process = delayed_options.fetch(:only_process, []).dup
|
46
|
+
only_process = only_process.call(self) if only_process.respond_to?(:call)
|
47
|
+
only_process.map(&:to_sym)
|
48
|
+
end
|
49
|
+
|
50
|
+
def process_delayed!
|
51
|
+
self.job_is_processing = true
|
52
|
+
self.post_processing = true
|
53
|
+
reprocess!(*delayed_only_process)
|
54
|
+
self.job_is_processing = false
|
55
|
+
update_processing_column
|
56
|
+
end
|
57
|
+
|
58
|
+
def processing_image_url
|
59
|
+
processing_image_url = delayed_options[:processing_image_url]
|
60
|
+
processing_image_url = processing_image_url.call(self) if processing_image_url.respond_to?(:call)
|
61
|
+
processing_image_url
|
62
|
+
end
|
63
|
+
|
64
|
+
def save
|
65
|
+
was_dirty = @dirty
|
66
|
+
|
67
|
+
super.tap do
|
68
|
+
if delay_processing? && was_dirty
|
69
|
+
instance.prepare_enqueueing_for name
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def reprocess_without_delay!(*style_args)
|
75
|
+
@post_processing_with_delay = true
|
76
|
+
reprocess!(*style_args)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def update_processing_column
|
82
|
+
if instance.respond_to?(:"#{name}_processing?")
|
83
|
+
instance.send("#{name}_processing=", false)
|
84
|
+
instance.class.unscoped.where(instance.class.primary_key => instance.id).update_all({ "#{name}_processing" => false })
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "active_job"
|
2
|
+
|
3
|
+
module DelayedPaperclip
|
4
|
+
class ProcessJob < ActiveJob::Base
|
5
|
+
def self.enqueue_delayed_paperclip(instance_klass, instance_id, attachment_name)
|
6
|
+
queue_name = instance_klass.constantize.paperclip_definitions[attachment_name][:delayed][:queue]
|
7
|
+
set(:queue => queue_name).perform_later(instance_klass, instance_id, attachment_name.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform(instance_klass, instance_id, attachment_name)
|
11
|
+
DelayedPaperclip.process_job(instance_klass, instance_id, attachment_name.to_sym)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "paperclip"
|
2
|
+
require "delayed_paperclip"
|
3
|
+
|
4
|
+
module DelayedPaperclip
|
5
|
+
# On initialzation, include DelayedPaperclip
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
initializer "delayed_paperclip.insert_into_active_record" do |app|
|
8
|
+
ActiveSupport.on_load :active_record do
|
9
|
+
DelayedPaperclip::Railtie.insert
|
10
|
+
end
|
11
|
+
|
12
|
+
if app.config.respond_to?(:delayed_paperclip_defaults)
|
13
|
+
DelayedPaperclip.options.merge!(app.config.delayed_paperclip_defaults)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Railtie
|
19
|
+
# Glue includes DelayedPaperclip Class Methods and Instance Methods into ActiveRecord
|
20
|
+
# Attachment and URL Generator extends Paperclip
|
21
|
+
def self.insert
|
22
|
+
ActiveRecord::Base.send(:include, DelayedPaperclip::Glue)
|
23
|
+
Paperclip::Attachment.prepend(DelayedPaperclip::Attachment)
|
24
|
+
Paperclip::Attachment.default_options[:url_generator] = DelayedPaperclip::UrlGenerator
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'paperclip/url_generator'
|
3
|
+
|
4
|
+
module DelayedPaperclip
|
5
|
+
class UrlGenerator < ::Paperclip::UrlGenerator
|
6
|
+
def initialize(attachment, _compatibility = nil)
|
7
|
+
@attachment = attachment
|
8
|
+
@attachment_options = attachment.options
|
9
|
+
end
|
10
|
+
|
11
|
+
def for(style_name, options)
|
12
|
+
most_appropriate_url = @attachment.processing_style?(style_name) ? most_appropriate_url(style_name) : most_appropriate_url()
|
13
|
+
timestamp_as_needed(
|
14
|
+
escape_url_as_needed(
|
15
|
+
@attachment_options[:interpolator].interpolate(most_appropriate_url, @attachment, style_name),
|
16
|
+
options
|
17
|
+
),
|
18
|
+
options)
|
19
|
+
end
|
20
|
+
|
21
|
+
# This method is a mess
|
22
|
+
def most_appropriate_url(style = nil)
|
23
|
+
if @attachment.processing_style?(style)
|
24
|
+
if @attachment.original_filename.nil? || delayed_default_url?(style)
|
25
|
+
|
26
|
+
if @attachment.delayed_options.nil? ||
|
27
|
+
@attachment.processing_image_url.nil? ||
|
28
|
+
!@attachment.processing?
|
29
|
+
default_url
|
30
|
+
else
|
31
|
+
@attachment.processing_image_url
|
32
|
+
end
|
33
|
+
|
34
|
+
else
|
35
|
+
@attachment_options[:url]
|
36
|
+
end
|
37
|
+
else
|
38
|
+
super()
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def timestamp_possible?
|
43
|
+
delayed_default_url? ? false : super
|
44
|
+
end
|
45
|
+
|
46
|
+
def delayed_default_url?(style = nil)
|
47
|
+
return false if @attachment.job_is_processing
|
48
|
+
return false if @attachment.dirty?
|
49
|
+
return false if not @attachment.delayed_options.try(:[], :url_with_processing)
|
50
|
+
return false if not processing?(style)
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def processing?(style)
|
57
|
+
return true if @attachment.processing?
|
58
|
+
return @attachment.processing_style?(style) if style
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,345 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DelayedPaperclip::Attachment do
|
4
|
+
before :each do
|
5
|
+
reset_dummy(dummy_options)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:dummy_options) { {} }
|
9
|
+
let(:dummy) { Dummy.create }
|
10
|
+
|
11
|
+
describe "#delayed_options" do
|
12
|
+
it "returns the specific options for delayed paperclip" do
|
13
|
+
expect(dummy.image.delayed_options).to eq({
|
14
|
+
:priority => 0,
|
15
|
+
:only_process => [],
|
16
|
+
:url_with_processing => true,
|
17
|
+
:processing_image_url => nil,
|
18
|
+
:queue => "paperclip"
|
19
|
+
})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#post_processing_with_delay" do
|
24
|
+
it "is true if delay_processing? is false" do
|
25
|
+
dummy.image.stubs(:delay_processing?).returns false
|
26
|
+
dummy.image.post_processing.should be_truthy
|
27
|
+
end
|
28
|
+
|
29
|
+
it "is false if delay_processing? is true" do
|
30
|
+
dummy.image.stubs(:delay_processing?).returns true
|
31
|
+
dummy.image.post_processing.should be_falsey
|
32
|
+
end
|
33
|
+
|
34
|
+
context "on a non-delayed image" do
|
35
|
+
let(:dummy_options) { { with_processed: false } }
|
36
|
+
|
37
|
+
it "is false if delay_processing? is true" do
|
38
|
+
dummy.image.stubs(:delay_processing?).returns true
|
39
|
+
dummy.image.post_processing.should be_falsey
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#delay_processing?" do
|
45
|
+
it "returns delayed_options existence if post_processing is nil" do
|
46
|
+
dummy.image.post_processing = nil
|
47
|
+
dummy.image.delay_processing?.should be_truthy
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns inverse of post_processing if it's set" do
|
51
|
+
dummy.image.post_processing = true
|
52
|
+
dummy.image.delay_processing?.should be_falsey
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#processing?" do
|
57
|
+
it "delegates to the dummy instance" do
|
58
|
+
dummy.expects(:image_processing?)
|
59
|
+
dummy.image.processing?
|
60
|
+
end
|
61
|
+
|
62
|
+
context "without a processing column" do
|
63
|
+
let(:dummy_options) { { with_processed: false } }
|
64
|
+
|
65
|
+
it "returns false" do
|
66
|
+
expect(dummy.image.processing?).to be_falsey
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#processing_style?" do
|
72
|
+
let(:style) { :background }
|
73
|
+
let(:processing_style?) { dummy.image.processing_style?(style) }
|
74
|
+
|
75
|
+
context "without a processing column" do
|
76
|
+
let(:dummy_options) { { with_processed: true, process_column: false } }
|
77
|
+
|
78
|
+
specify { expect(processing_style?).to be_falsey }
|
79
|
+
end
|
80
|
+
|
81
|
+
context "with a processing column" do
|
82
|
+
context "when not processing" do
|
83
|
+
before { dummy.image_processing = false }
|
84
|
+
|
85
|
+
specify { expect(processing_style?).to be_falsey }
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when processing" do
|
89
|
+
before { dummy.image_processing = true }
|
90
|
+
|
91
|
+
context "when not split processing" do
|
92
|
+
specify { expect(processing_style?).to be_truthy }
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when split processing" do
|
96
|
+
context "when delayed :only_process is an Array" do
|
97
|
+
let(:dummy_options) { {
|
98
|
+
paperclip: {
|
99
|
+
styles: {
|
100
|
+
online: "400x400x",
|
101
|
+
background: "600x600x"
|
102
|
+
},
|
103
|
+
only_process: [:online]
|
104
|
+
},
|
105
|
+
|
106
|
+
only_process: [:background]
|
107
|
+
}}
|
108
|
+
|
109
|
+
specify { expect(processing_style?).to be }
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when delayed :only_process is callable" do
|
113
|
+
let(:dummy_options) { {
|
114
|
+
paperclip: {
|
115
|
+
styles: {
|
116
|
+
online: "400x400x",
|
117
|
+
background: "600x600x"
|
118
|
+
},
|
119
|
+
only_process: [:online]
|
120
|
+
},
|
121
|
+
|
122
|
+
only_process: lambda { |a| [:background] }
|
123
|
+
}}
|
124
|
+
|
125
|
+
specify { expect(processing_style?).to be }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#delayed_only_process" do
|
133
|
+
context "without only_process options" do
|
134
|
+
it "returns []" do
|
135
|
+
expect(dummy.image.delayed_only_process).to eq []
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "with only_process options" do
|
140
|
+
before :each do
|
141
|
+
reset_dummy(paperclip: { only_process: [:small, :large] } )
|
142
|
+
end
|
143
|
+
|
144
|
+
it "returns [:small, :large]" do
|
145
|
+
expect(dummy.image.delayed_only_process).to eq [:small, :large]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "with only_process set with callable" do
|
150
|
+
before :each do
|
151
|
+
reset_dummy(paperclip: { only_process: lambda { |a| [:small, :large] } } )
|
152
|
+
end
|
153
|
+
|
154
|
+
# Enable when https://github.com/thoughtbot/paperclip/pull/2289 is resolved
|
155
|
+
xit "returns [:small, :large]" do
|
156
|
+
expect(dummy.image.delayed_only_process).to eq [:small, :large]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "#process_delayed!" do
|
162
|
+
it "sets job_is_processing to true" do
|
163
|
+
dummy.image.expects(:job_is_processing=).with(true).once
|
164
|
+
dummy.image.expects(:job_is_processing=).with(false).once
|
165
|
+
dummy.image.process_delayed!
|
166
|
+
end
|
167
|
+
|
168
|
+
it "sets post_processing to true" do
|
169
|
+
dummy.image.expects(:post_processing=).with(true).once
|
170
|
+
dummy.image.process_delayed!
|
171
|
+
end
|
172
|
+
|
173
|
+
context "without only_process options" do
|
174
|
+
it "calls reprocess!" do
|
175
|
+
dummy.image.expects(:reprocess!)
|
176
|
+
dummy.image.process_delayed!
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context "with only_process options" do
|
181
|
+
before :each do
|
182
|
+
reset_dummy(paperclip: { only_process: [:small, :large] } )
|
183
|
+
end
|
184
|
+
|
185
|
+
it "calls reprocess! with options" do
|
186
|
+
dummy.image.expects(:reprocess!).with(:small, :large)
|
187
|
+
dummy.image.process_delayed!
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "with only_process set with callable" do
|
192
|
+
before :each do
|
193
|
+
reset_dummy(paperclip: { only_process: lambda { |a| [:small, :large] } } )
|
194
|
+
end
|
195
|
+
|
196
|
+
# Enable when https://github.com/thoughtbot/paperclip/pull/2289 is resolved
|
197
|
+
xit "calls reprocess! with options" do
|
198
|
+
dummy.image.expects(:reprocess!).with(:small, :large)
|
199
|
+
dummy.image.process_delayed!
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe "#processing_image_url" do
|
205
|
+
context "no url" do
|
206
|
+
it "returns nil" do
|
207
|
+
dummy.image.processing_image_url.should be_nil
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context "static url" do
|
212
|
+
before :each do
|
213
|
+
reset_dummy(:processing_image_url => "/foo/bar.jpg")
|
214
|
+
end
|
215
|
+
|
216
|
+
it "returns given url" do
|
217
|
+
dummy.image.processing_image_url.should == "/foo/bar.jpg"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context "proc" do
|
222
|
+
before :each do
|
223
|
+
reset_dummy(:processing_image_url => proc { "Hello/World" } )
|
224
|
+
end
|
225
|
+
|
226
|
+
it "returns evaluates proc" do
|
227
|
+
dummy.image.processing_image_url.should == "Hello/World"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe "#update_processing_column" do
|
233
|
+
it "updates the column to false" do
|
234
|
+
dummy.update_attribute(:image_processing, true)
|
235
|
+
|
236
|
+
dummy.image.send(:update_processing_column)
|
237
|
+
|
238
|
+
dummy.reload.image_processing.should be_falsey
|
239
|
+
end
|
240
|
+
|
241
|
+
context 'with a default scope on the model excluding the instance' do
|
242
|
+
let(:dummy_options) do
|
243
|
+
{ :default_scope => lambda { Dummy.where(hidden: false) } }
|
244
|
+
end
|
245
|
+
|
246
|
+
let!(:dummy) { Dummy.create(hidden: true) }
|
247
|
+
|
248
|
+
specify { Dummy.count.should be 0 }
|
249
|
+
specify { Dummy.unscoped.count.should be 1 }
|
250
|
+
|
251
|
+
it "ignores the default scope and updates the column to false" do
|
252
|
+
dummy.update_attribute(:image_processing, true)
|
253
|
+
dummy.image.send(:update_processing_column)
|
254
|
+
dummy.reload.image_processing.should be_falsey
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
describe "#save" do
|
260
|
+
context "delay processing and it was dirty" do
|
261
|
+
before :each do
|
262
|
+
dummy.image.stubs(:delay_processing?).returns true
|
263
|
+
dummy.image.instance_variable_set(:@dirty, true)
|
264
|
+
end
|
265
|
+
|
266
|
+
it "prepares the enqueing" do
|
267
|
+
dummy.expects(:prepare_enqueueing_for).with(:image)
|
268
|
+
dummy.image.save
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context "without dirty or delay_processing" do
|
273
|
+
it "does not prepare_enqueueing" do
|
274
|
+
dummy.expects(:prepare_enqueueing_for).with(:image).never
|
275
|
+
dummy.image.save
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
describe "#reprocess_without_delay!" do
|
281
|
+
it "sets post post_processing_with_delay and reprocesses with given args" do
|
282
|
+
dummy.image.expects(:reprocess!).with(:small)
|
283
|
+
dummy.image.reprocess_without_delay!(:small)
|
284
|
+
dummy.image.instance_variable_get(:@post_processing_with_delay).should == true
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
describe "#split_processing?" do
|
289
|
+
let(:split_processing?) { dummy.image.split_processing? }
|
290
|
+
|
291
|
+
let(:paperclip_styles) { {
|
292
|
+
online: "400x400x",
|
293
|
+
background: "600x600x"
|
294
|
+
} }
|
295
|
+
|
296
|
+
context ":only_process option is set on attachment" do
|
297
|
+
let(:dummy_options) { {
|
298
|
+
paperclip: {
|
299
|
+
styles: paperclip_styles,
|
300
|
+
only_process: [:online]
|
301
|
+
},
|
302
|
+
|
303
|
+
only_process: delayed_only_process
|
304
|
+
}}
|
305
|
+
|
306
|
+
context "processing different styles in background" do
|
307
|
+
context "when delayed :only_process is an Array" do
|
308
|
+
let(:delayed_only_process) { [:background] }
|
309
|
+
|
310
|
+
specify { expect(split_processing?).to be true }
|
311
|
+
end
|
312
|
+
|
313
|
+
context "when delayed :only_process is callable" do
|
314
|
+
let(:delayed_only_process) { lambda { |a| [:background] } }
|
315
|
+
|
316
|
+
specify { expect(split_processing?).to be true }
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
context "processing same styles in background" do
|
321
|
+
context "when delayed :only_process is an Array" do
|
322
|
+
let(:delayed_only_process) { [:online] }
|
323
|
+
|
324
|
+
specify { expect(split_processing?).to be false }
|
325
|
+
end
|
326
|
+
|
327
|
+
context "when delayed :only_process is callable" do
|
328
|
+
let(:delayed_only_process) { lambda { |a| [:online] } }
|
329
|
+
|
330
|
+
specify { expect(split_processing?).to be false }
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context ":only_process option is not set on attachment" do
|
336
|
+
let(:dummy_options) { {
|
337
|
+
paperclip: {
|
338
|
+
styles: paperclip_styles
|
339
|
+
}
|
340
|
+
}}
|
341
|
+
|
342
|
+
specify { expect(split_processing?).to be false }
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|