carrierwave_backgrounder 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +8 -0
- data/CHANGELOG.md +6 -1
- data/README.md +21 -2
- data/carrierwave_backgrounder.gemspec +3 -4
- data/lib/backgrounder/orm/activemodel.rb +19 -13
- data/lib/backgrounder/orm/base.rb +26 -29
- data/lib/backgrounder/orm/data_mapper.rb +14 -28
- data/lib/backgrounder/support/backends.rb +43 -26
- data/lib/backgrounder/version.rb +1 -1
- data/lib/backgrounder/workers/process_asset.rb +9 -5
- data/lib/backgrounder/workers/store_asset.rb +19 -9
- data/lib/carrierwave_backgrounder.rb +2 -1
- data/spec/backgrounder/orm/activemodel_spec.rb +61 -4
- data/spec/backgrounder/orm/base_spec.rb +15 -44
- data/spec/backgrounder/support/backends_spec.rb +163 -29
- data/spec/backgrounder/workers/fixtures/{test.jpg → images/test.jpg} +0 -0
- data/spec/backgrounder/workers/process_asset_spec.rb +38 -14
- data/spec/backgrounder/workers/store_asset_spec.rb +63 -11
- data/spec/spec_helper.rb +0 -1
- data/spec/support/backend_constants.rb +8 -0
- data/spec/support/mock_worker.rb +17 -0
- metadata +14 -10
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 0.1.3
|
2
|
+
|
3
|
+
### enhancements
|
4
|
+
* CarrierWave::Workers::ProcessAsset now uses #update_attribute when setting [column]_processing.
|
5
|
+
|
1
6
|
## 0.1.2
|
2
7
|
|
3
8
|
### enhancements
|
@@ -7,7 +12,7 @@
|
|
7
12
|
```
|
8
13
|
|
9
14
|
### bug fixes
|
10
|
-
* Check [column]_cache to make sure we are
|
15
|
+
* Check [column]_cache to make sure we are processing when a form fails and [column]_cache is used.
|
11
16
|
|
12
17
|
## 0.1.1
|
13
18
|
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# CarrierWave Backgrounder
|
1
|
+
# CarrierWave Backgrounder
|
2
|
+
|
3
|
+
[](http://travis-ci.org/lardawge/carrierwave_backgrounder)
|
4
|
+
[](https://codeclimate.com/github/lardawge/carrierwave_backgrounder)
|
2
5
|
|
3
6
|
I like CarrierWave. That being said, I don't like tying up app instances waiting for images to process.
|
4
7
|
|
@@ -35,6 +38,8 @@ These instructions assume you have previously set up [CarrierWave](https://githu
|
|
35
38
|
In Rails, add the following your Gemfile:
|
36
39
|
|
37
40
|
```ruby
|
41
|
+
# IMPORTANT: Be sure to list the backend job processor you intend to use, before carrierwave_backgrounder
|
42
|
+
gem 'sidekiq' # or delayed_job, resque, ect...
|
38
43
|
gem 'carrierwave_backgrounder'
|
39
44
|
```
|
40
45
|
|
@@ -105,7 +110,21 @@ To overide the worker in cases where additional methods need to be called or you
|
|
105
110
|
second argument:
|
106
111
|
|
107
112
|
```ruby
|
108
|
-
process_in_background :avatar,
|
113
|
+
process_in_background :avatar, MyParanoidWorker
|
114
|
+
```
|
115
|
+
|
116
|
+
Then create a worker that subclasses carrierwave_backgrounder's worker:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
class MyParanoidWorker < ::CarrierWave::Workers::ProcessAsset
|
120
|
+
# ...or subclass CarrierWave::Workers::StoreAsset if you're using store_in_background
|
121
|
+
|
122
|
+
def error(job, exception)
|
123
|
+
report_job_failure # or whatever
|
124
|
+
end
|
125
|
+
|
126
|
+
# other hooks you might care about
|
127
|
+
end
|
109
128
|
```
|
110
129
|
### Testing with Rspec
|
111
130
|
We use the after_commit hook when using active_record. This creates a problem when testing with Rspec because after_commit never gets fired
|
@@ -8,10 +8,9 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Larry Sprock"]
|
10
10
|
s.email = ["larry@lucidbleu.com"]
|
11
|
-
s.homepage = ""
|
12
|
-
s.
|
13
|
-
|
14
|
-
s.rubyforge_project = "carrierwave_backgrounder"
|
11
|
+
s.homepage = "https://github.com/lardawge/carrierwave_backgrounder"
|
12
|
+
s.licenses = ["MIT"]
|
13
|
+
s.summary = %q{Offload CarrierWave's image processing and storage to a background process using Delayed Job, Resque, Sidekiq, Qu, Queue Classic or Girl Friday}
|
15
14
|
|
16
15
|
s.files = `git ls-files`.split("\n")
|
17
16
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -8,25 +8,31 @@ module CarrierWave
|
|
8
8
|
include CarrierWave::Backgrounder::ORM::Base
|
9
9
|
|
10
10
|
def process_in_background(column, worker=::CarrierWave::Workers::ProcessAsset)
|
11
|
+
before_save :"set_#{column}_processing", :if => :"enqueue_#{column}_background_job?"
|
12
|
+
send _supported_am_after_callback, :"enqueue_#{column}_background_job", :if => :"enqueue_#{column}_background_job?"
|
11
13
|
super
|
12
|
-
|
13
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
14
|
-
def trigger_#{column}_background_processing?
|
15
|
-
process_#{column}_upload != true &&
|
16
|
-
(#{column}_changed? || previous_changes.has_key?(:#{column}) || remote_#{column}_url.present? || #{column}_cache.present?)
|
17
|
-
end
|
18
|
-
RUBY
|
19
14
|
end
|
20
15
|
|
21
16
|
def store_in_background(column, worker=::CarrierWave::Workers::StoreAsset)
|
17
|
+
send _supported_am_after_callback, :"enqueue_#{column}_background_job", :if => :"enqueue_#{column}_background_job?"
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def _supported_am_after_callback
|
24
|
+
respond_to?(:after_commit) ? :after_commit : :after_save
|
25
|
+
end
|
26
|
+
|
27
|
+
def _define_shared_backgrounder_methods(mod, column, worker)
|
22
28
|
super
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
define_method :"#{column}_updated?" do
|
31
|
+
send(:"#{column}_changed?") || # after_save support
|
32
|
+
previous_changes.has_key?(:"#{column}") || # after_commit support
|
33
|
+
send(:"remote_#{column}_url").present? || # Remote upload support
|
34
|
+
send(:"#{column}_cache").present? # Form failure support
|
35
|
+
end
|
30
36
|
end
|
31
37
|
end # ActiveModel
|
32
38
|
|
@@ -39,27 +39,17 @@ module CarrierWave
|
|
39
39
|
# end
|
40
40
|
#
|
41
41
|
def process_in_background(column, worker=::CarrierWave::Workers::ProcessAsset)
|
42
|
-
|
43
|
-
|
44
|
-
send :before_save, :"set_#{column}_processing", :if => :"trigger_#{column}_background_processing?"
|
45
|
-
callback = self.respond_to?(:after_commit) ? :after_commit : :after_save
|
46
|
-
send callback, :"enqueue_#{column}_background_job", :if => :"trigger_#{column}_background_processing?"
|
47
|
-
|
48
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
42
|
+
attr_accessor :"process_#{column}_upload"
|
49
43
|
|
44
|
+
mod = Module.new
|
45
|
+
include mod
|
46
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
50
47
|
def set_#{column}_processing
|
51
48
|
self.#{column}_processing = true if respond_to?(:#{column}_processing)
|
52
49
|
end
|
53
|
-
|
54
|
-
def enqueue_#{column}_background_job
|
55
|
-
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id.to_s, #{column}.mounted_as)
|
56
|
-
end
|
57
|
-
|
58
|
-
def trigger_#{column}_background_processing?
|
59
|
-
process_#{column}_upload != true
|
60
|
-
end
|
61
|
-
|
62
50
|
RUBY
|
51
|
+
|
52
|
+
_define_shared_backgrounder_methods(mod, column, worker)
|
63
53
|
end
|
64
54
|
|
65
55
|
##
|
@@ -85,30 +75,37 @@ module CarrierWave
|
|
85
75
|
# end
|
86
76
|
#
|
87
77
|
def store_in_background(column, worker=::CarrierWave::Workers::StoreAsset)
|
88
|
-
|
89
|
-
|
90
|
-
callback = self.respond_to?(:after_commit) ? :after_commit : :after_save
|
91
|
-
send callback, :"enqueue_#{column}_background_job", :if => :"trigger_#{column}_background_storage?"
|
92
|
-
|
93
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
78
|
+
attr_accessor :"process_#{column}_upload"
|
94
79
|
|
80
|
+
mod = Module.new
|
81
|
+
include mod
|
82
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
95
83
|
def write_#{column}_identifier
|
96
|
-
super
|
84
|
+
super and return if process_#{column}_upload
|
97
85
|
self.#{column}_tmp = _mounter(:#{column}).cache_name if _mounter(:#{column}).cache_name
|
98
86
|
end
|
99
87
|
|
100
88
|
def store_#{column}!
|
101
|
-
super
|
89
|
+
super if process_#{column}_upload
|
102
90
|
end
|
91
|
+
RUBY
|
103
92
|
|
104
|
-
|
105
|
-
|
106
|
-
end
|
93
|
+
_define_shared_backgrounder_methods(mod, column, worker)
|
94
|
+
end
|
107
95
|
|
108
|
-
|
109
|
-
|
96
|
+
private
|
97
|
+
|
98
|
+
def _define_shared_backgrounder_methods(mod, column, worker)
|
99
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
100
|
+
def #{column}_updated?; true; end
|
101
|
+
|
102
|
+
def enqueue_#{column}_background_job?
|
103
|
+
!process_#{column}_upload && #{column}_updated?
|
110
104
|
end
|
111
105
|
|
106
|
+
def enqueue_#{column}_background_job
|
107
|
+
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id.to_s, #{column}.mounted_as)
|
108
|
+
end
|
112
109
|
RUBY
|
113
110
|
end
|
114
111
|
|
@@ -10,60 +10,46 @@ module CarrierWave
|
|
10
10
|
after :save, :"enqueue_#{column}_background_job"
|
11
11
|
|
12
12
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
13
|
-
attr_accessor :process_#{column}_upload
|
14
|
-
attr_reader :#{column}_changed
|
15
|
-
|
16
13
|
def set_#{column}_processing
|
17
14
|
@#{column}_changed = attribute_dirty?(:#{column})
|
18
|
-
self.#{column}_processing = true if respond_to?(:#{column}_processing)
|
15
|
+
self.#{column}_processing = true if respond_to?(:#{column}_processing)
|
19
16
|
end
|
20
|
-
|
21
|
-
def enqueue_#{column}_background_job
|
22
|
-
if trigger_#{column}_background_processing?
|
23
|
-
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id, #{column}.mounted_as)
|
24
|
-
@#{column}_changed = false
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def trigger_#{column}_background_processing?
|
29
|
-
process_#{column}_upload != true && #{column}_changed
|
30
|
-
end
|
31
|
-
|
32
17
|
RUBY
|
33
18
|
end
|
34
19
|
|
35
20
|
def store_in_background(column, worker=::CarrierWave::Workers::StoreAsset)
|
36
21
|
before :save, :"set_#{column}_changed"
|
37
|
-
after
|
22
|
+
after :save, :"enqueue_#{column}_background_job"
|
38
23
|
|
39
24
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
40
|
-
attr_accessor :process_#{column}_upload
|
41
|
-
attr_reader :#{column}_changed
|
42
|
-
|
43
25
|
def set_#{column}_changed
|
44
26
|
@#{column}_changed = attribute_dirty?(:#{column})
|
45
27
|
end
|
46
28
|
|
47
29
|
def write_#{column}_identifier
|
48
|
-
super
|
30
|
+
super and return if process_#{column}_upload
|
49
31
|
self.#{column}_tmp = _mounter(:#{column}).cache_name
|
50
32
|
end
|
33
|
+
RUBY
|
34
|
+
end
|
51
35
|
|
52
|
-
|
53
|
-
|
54
|
-
|
36
|
+
private
|
37
|
+
|
38
|
+
def _define_shared_backgrounder_methods(mod, column, worker)
|
39
|
+
super
|
40
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
41
|
+
attr_reader :#{column}_changed
|
55
42
|
|
56
43
|
def enqueue_#{column}_background_job
|
57
|
-
if
|
44
|
+
if enqueue_#{column}_background_job?
|
58
45
|
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id, #{column}.mounted_as)
|
59
46
|
@#{column}_changed = false
|
60
47
|
end
|
61
48
|
end
|
62
49
|
|
63
|
-
def
|
64
|
-
|
50
|
+
def #{column}_updated?
|
51
|
+
#{column}_changed
|
65
52
|
end
|
66
|
-
|
67
53
|
RUBY
|
68
54
|
end
|
69
55
|
end # DataMapper
|
@@ -25,34 +25,12 @@ module Support
|
|
25
25
|
backends << :qu if defined? ::Qu
|
26
26
|
backends << :sidekiq if defined? ::Sidekiq
|
27
27
|
backends << :qc if defined? ::QC
|
28
|
-
backends
|
28
|
+
backends
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
def enqueue_for_backend(worker, class_name, subject_id, mounted_as)
|
33
|
-
|
34
|
-
when :girl_friday
|
35
|
-
@girl_friday_queue ||= GirlFriday::WorkQueue.new(queue_options.delete(:queue) || :carrierwave, queue_options) do |msg|
|
36
|
-
worker = msg[:worker]
|
37
|
-
worker.perform
|
38
|
-
end
|
39
|
-
@girl_friday_queue << { :worker => worker.new(class_name, subject_id, mounted_as) }
|
40
|
-
when :delayed_job
|
41
|
-
::Delayed::Job.enqueue worker.new(class_name, subject_id, mounted_as), :queue => queue_options[:queue]
|
42
|
-
when :resque
|
43
|
-
worker.instance_variable_set('@queue', queue_options[:queue] || :carrierwave)
|
44
|
-
::Resque.enqueue worker, class_name, subject_id, mounted_as
|
45
|
-
when :qu
|
46
|
-
worker.instance_variable_set('@queue', queue_options[:queue] || :carrierwave)
|
47
|
-
::Qu.enqueue worker, class_name, subject_id, mounted_as
|
48
|
-
when :sidekiq
|
49
|
-
worker.sidekiq_options queue_options
|
50
|
-
::Sidekiq::Client.enqueue worker, class_name, subject_id, mounted_as
|
51
|
-
when :qc
|
52
|
-
::QC.enqueue "#{worker.name}.perform", class_name, subject_id, mounted_as.to_s
|
53
|
-
when :immediate
|
54
|
-
worker.new(class_name, subject_id, mounted_as).perform
|
55
|
-
end
|
33
|
+
self.send :"enqueue_#{backend}", worker, class_name, subject_id, mounted_as
|
56
34
|
end
|
57
35
|
|
58
36
|
private
|
@@ -62,13 +40,52 @@ module Support
|
|
62
40
|
warn 'WARNING: No available queue backends found for CarrierWave::Backgrounder. Using the :immediate.'
|
63
41
|
:immediate
|
64
42
|
elsif available_backends.size > 1
|
65
|
-
raise ::CarrierWave::Backgrounder::
|
66
|
-
"You have
|
43
|
+
raise ::CarrierWave::Backgrounder::TooManyBackendsAvailableError,
|
44
|
+
"You have too many backends available: #{available_backends.inspect}. Please specify which one to use in configuration block"
|
67
45
|
else
|
68
46
|
available_backends.first
|
69
47
|
end
|
70
48
|
end
|
71
49
|
|
50
|
+
def enqueue_delayed_job(worker, *args)
|
51
|
+
::Delayed::Job.enqueue worker.new(*args), :queue => queue_options[:queue]
|
52
|
+
end
|
53
|
+
|
54
|
+
def enqueue_resque(worker, *args)
|
55
|
+
worker.instance_variable_set('@queue', queue_options[:queue] || :carrierwave)
|
56
|
+
::Resque.enqueue worker, *args
|
57
|
+
end
|
58
|
+
|
59
|
+
def enqueue_sidekiq(worker, *args)
|
60
|
+
sidekiq_client_args = { 'class' => worker, 'args' => args }
|
61
|
+
sidekiq_client_args['queue'] = queue_options[:queue] unless queue_options[:queue].nil?
|
62
|
+
sidekiq_client_args['retry'] = queue_options[:retry] unless queue_options[:retry].nil?
|
63
|
+
sidekiq_client_args['timeout'] = queue_options[:timeout] unless queue_options[:timeout].nil?
|
64
|
+
sidekiq_client_args['backtrace'] = queue_options[:backtrace] unless queue_options[:backtrace].nil?
|
65
|
+
worker.client_push(sidekiq_client_args)
|
66
|
+
end
|
67
|
+
|
68
|
+
def enqueue_girl_friday(worker, *args)
|
69
|
+
@girl_friday_queue ||= GirlFriday::WorkQueue.new(queue_options.delete(:queue) || :carrierwave, queue_options) do |msg|
|
70
|
+
worker = msg[:worker]
|
71
|
+
worker.perform
|
72
|
+
end
|
73
|
+
@girl_friday_queue << { :worker => worker.new(*args) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def enqueue_qu(worker, *args)
|
77
|
+
worker.instance_variable_set('@queue', queue_options[:queue] || :carrierwave)
|
78
|
+
::Qu.enqueue worker, *args
|
79
|
+
end
|
80
|
+
|
81
|
+
def enqueue_qc(worker, *args)
|
82
|
+
class_name, subject_id, mounted_as = args
|
83
|
+
::QC.enqueue "#{worker.name}.perform", class_name, subject_id, mounted_as.to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
def enqueue_immediate(worker, *args)
|
87
|
+
worker.new(*args).perform
|
88
|
+
end
|
72
89
|
end
|
73
90
|
end
|
74
91
|
end
|
data/lib/backgrounder/version.rb
CHANGED
@@ -10,23 +10,27 @@ module CarrierWave
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def perform(*args)
|
13
|
-
set_args(*args)
|
14
|
-
|
15
|
-
record = resource.find id
|
13
|
+
set_args(*args) if args.present?
|
14
|
+
record = constantized_resource.find id
|
16
15
|
|
17
16
|
if record
|
18
17
|
record.send(:"process_#{column}_upload=", true)
|
19
18
|
if record.send(:"#{column}").recreate_versions! && record.respond_to?(:"#{column}_processing")
|
20
|
-
record.
|
21
|
-
record.save!
|
19
|
+
record.update_attribute :"#{column}_processing", nil
|
22
20
|
end
|
23
21
|
end
|
24
22
|
end
|
25
23
|
|
24
|
+
private
|
25
|
+
|
26
26
|
def set_args(klass, id, column)
|
27
27
|
self.klass, self.id, self.column = klass, id, column
|
28
28
|
end
|
29
29
|
|
30
|
+
def constantized_resource
|
31
|
+
klass.is_a?(String) ? klass.constantize : klass
|
32
|
+
end
|
33
|
+
|
30
34
|
end # ProcessAsset
|
31
35
|
|
32
36
|
end # Workers
|
@@ -4,33 +4,43 @@ module CarrierWave
|
|
4
4
|
|
5
5
|
class StoreAsset < Struct.new(:klass, :id, :column)
|
6
6
|
include ::Sidekiq::Worker if defined?(::Sidekiq)
|
7
|
+
attr_reader :cache_path, :tmp_directory
|
7
8
|
|
8
9
|
def self.perform(*args)
|
9
10
|
new(*args).perform
|
10
11
|
end
|
11
12
|
|
12
13
|
def perform(*args)
|
13
|
-
set_args(*args)
|
14
|
-
|
15
|
-
|
16
|
-
if
|
17
|
-
|
18
|
-
cache_dir = [asset.root, asset.cache_dir].join("/")
|
19
|
-
cache_path = [cache_dir, tmp].join("/")
|
20
|
-
tmp_dir = [cache_dir, tmp.split("/")[0]].join("/")
|
14
|
+
set_args(*args) if args.present?
|
15
|
+
record = constantized_resource.find id
|
16
|
+
|
17
|
+
if record.send(:"#{column}_tmp")
|
18
|
+
store_directories(record)
|
21
19
|
record.send :"process_#{column}_upload=", true
|
22
20
|
record.send :"#{column}_tmp=", nil
|
23
21
|
File.open(cache_path) { |f| record.send :"#{column}=", f }
|
24
22
|
if record.save!
|
25
|
-
FileUtils.rm_r(
|
23
|
+
FileUtils.rm_r(tmp_directory, :force => true)
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
28
|
+
private
|
29
|
+
|
30
30
|
def set_args(klass, id, column)
|
31
31
|
self.klass, self.id, self.column = klass, id, column
|
32
32
|
end
|
33
33
|
|
34
|
+
def constantized_resource
|
35
|
+
klass.is_a?(String) ? klass.constantize : klass
|
36
|
+
end
|
37
|
+
|
38
|
+
def store_directories(record)
|
39
|
+
asset, asset_tmp = record.send(:"#{column}"), record.send(:"#{column}_tmp")
|
40
|
+
cache_directory = File.join(asset.root, asset.cache_dir)
|
41
|
+
@cache_path = File.join(cache_directory, asset_tmp)
|
42
|
+
@tmp_directory = File.join(cache_directory, asset_tmp.split("/").first)
|
43
|
+
end
|
34
44
|
end # StoreAsset
|
35
45
|
|
36
46
|
end # Workers
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/object'
|
1
2
|
require 'backgrounder/support/backends'
|
2
3
|
require 'backgrounder/orm/base'
|
3
4
|
require 'backgrounder/delay'
|
@@ -7,7 +8,7 @@ module CarrierWave
|
|
7
8
|
include Support::Backends
|
8
9
|
|
9
10
|
class UnsupportedBackendError < StandardError ; end
|
10
|
-
class
|
11
|
+
class TooManyBackendsAvailableError < StandardError ; end
|
11
12
|
|
12
13
|
def self.configure
|
13
14
|
yield self
|
@@ -13,14 +13,71 @@ describe CarrierWave::Backgrounder::ORM::ActiveModel do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
@mock_class.extend CarrierWave::Backgrounder::ORM::ActiveModel
|
16
|
-
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.store_in_background' do
|
19
|
+
context 'setting up callbacks' do
|
20
|
+
it 'creates an after_commit hook' do
|
21
|
+
@mock_class.expects(:after_commit).with(:enqueue_avatar_background_job, :if => :enqueue_avatar_background_job?)
|
22
|
+
@mock_class.store_in_background :avatar
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '.process_in_background' do
|
28
|
+
context 'setting up callbacks' do
|
29
|
+
it 'creates a before_save hook' do
|
30
|
+
@mock_class.expects(:before_save).with(:set_avatar_processing, :if => :enqueue_avatar_background_job?)
|
31
|
+
@mock_class.process_in_background :avatar
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'creates an after_save hook' do
|
35
|
+
@mock_class.expects(:after_commit).with(:enqueue_avatar_background_job, :if => :enqueue_avatar_background_job?)
|
36
|
+
@mock_class.process_in_background :avatar
|
37
|
+
end
|
38
|
+
end
|
17
39
|
end
|
18
40
|
|
19
41
|
describe '#trigger_column_background_processing?' do
|
20
|
-
|
21
|
-
|
42
|
+
let(:instance) { @mock_class.new }
|
43
|
+
|
44
|
+
before do
|
45
|
+
@mock_class.process_in_background :avatar
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns true if process_avatar_upload is false" do
|
22
49
|
instance.expects(:process_avatar_upload)
|
23
|
-
instance.
|
50
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "calls column_changed?" do
|
54
|
+
instance.expects(:process_avatar_upload).returns(false)
|
55
|
+
instance.expects(:avatar_changed?)
|
56
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
57
|
+
end
|
58
|
+
|
59
|
+
it "calls previous_changes" do
|
60
|
+
instance.expects(:process_avatar_upload).returns(false)
|
61
|
+
instance.expects(:avatar_changed?).returns(false)
|
62
|
+
instance.expects(:previous_changes).returns({:avatar => true})
|
63
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
it "calls avatar_remote_url" do
|
67
|
+
instance.expects(:process_avatar_upload).returns(false)
|
68
|
+
instance.expects(:avatar_changed?).returns(false)
|
69
|
+
instance.expects(:previous_changes).returns({})
|
70
|
+
instance.expects(:remote_avatar_url).returns('yup')
|
71
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "calls avatar_cache" do
|
75
|
+
instance.expects(:process_avatar_upload).returns(false)
|
76
|
+
instance.expects(:avatar_changed?).returns(false)
|
77
|
+
instance.expects(:previous_changes).returns({})
|
78
|
+
instance.expects(:remote_avatar_url).returns(nil)
|
79
|
+
instance.expects(:avatar_cache).returns('yup')
|
80
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
24
81
|
end
|
25
82
|
end
|
26
83
|
end
|
@@ -12,64 +12,37 @@ describe CarrierWave::Backgrounder::ORM::Base do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'mixes in the two DSL methods' do
|
15
|
-
@mock_class.
|
16
|
-
@mock_class.
|
15
|
+
expect(@mock_class).to respond_to(:process_in_background)
|
16
|
+
expect(@mock_class).to respond_to(:store_in_background)
|
17
17
|
end
|
18
18
|
|
19
|
-
describe '
|
20
|
-
|
21
|
-
describe 'setting up callbacks' do
|
22
|
-
|
23
|
-
it 'creates a before_save hook' do
|
24
|
-
@mock_class.expects(:before_save).with(:set_avatar_processing, :if => :trigger_avatar_background_processing?)
|
25
|
-
@mock_class.process_in_background :avatar
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'creates an after_save hook' do
|
29
|
-
@mock_class.expects(:after_commit).with(:enqueue_avatar_background_job, :if => :trigger_avatar_background_processing?)
|
30
|
-
@mock_class.process_in_background :avatar
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
describe 'including new methods' do
|
19
|
+
describe '.process_in_background' do
|
20
|
+
context 'including new methods' do
|
36
21
|
before do
|
37
22
|
@mock_class.process_in_background :avatar
|
38
23
|
@instance = @mock_class.new
|
39
24
|
end
|
40
25
|
|
41
26
|
it 'creates a processing enabled accessor' do
|
42
|
-
@instance.
|
43
|
-
@instance.
|
27
|
+
expect(@instance).to respond_to(:process_avatar_upload)
|
28
|
+
expect(@instance).to respond_to(:process_avatar_upload=)
|
44
29
|
end
|
45
30
|
|
46
31
|
it 'create a setter for the processing attribute' do
|
47
|
-
@instance.
|
32
|
+
expect(@instance).to respond_to(:set_avatar_processing)
|
48
33
|
end
|
49
34
|
|
50
35
|
it 'create a background job queuer' do
|
51
|
-
@instance.
|
36
|
+
expect(@instance).to respond_to(:enqueue_avatar_background_job)
|
52
37
|
end
|
53
38
|
|
54
39
|
it 'create a trigger interrogator' do
|
55
|
-
@instance.
|
40
|
+
expect(@instance).to respond_to(:enqueue_avatar_background_job?)
|
56
41
|
end
|
57
|
-
|
58
42
|
end
|
59
|
-
|
60
43
|
end
|
61
44
|
|
62
45
|
describe 'store in background' do
|
63
|
-
|
64
|
-
describe 'setting up callbacks' do
|
65
|
-
|
66
|
-
it 'creates an after_save hook' do
|
67
|
-
@mock_class.expects(:after_commit).with(:enqueue_avatar_background_job, :if => :trigger_avatar_background_storage?)
|
68
|
-
@mock_class.store_in_background :avatar
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
46
|
describe 'including new methods' do
|
74
47
|
before do
|
75
48
|
@mock_class.store_in_background :avatar
|
@@ -77,27 +50,25 @@ describe CarrierWave::Backgrounder::ORM::Base do
|
|
77
50
|
end
|
78
51
|
|
79
52
|
it 'creates a processing enabled accessor' do
|
80
|
-
@instance.
|
81
|
-
@instance.
|
53
|
+
expect(@instance).to respond_to(:process_avatar_upload)
|
54
|
+
expect(@instance).to respond_to(:process_avatar_upload=)
|
82
55
|
end
|
83
56
|
|
84
57
|
it 'overrides the write column identifier method from carrierwave' do
|
85
|
-
@instance.
|
58
|
+
expect(@instance).to respond_to(:write_avatar_identifier)
|
86
59
|
end
|
87
60
|
|
88
61
|
it 'overrides the store column method from carrierwave' do
|
89
|
-
@instance.
|
62
|
+
expect(@instance).to respond_to(:store_avatar!)
|
90
63
|
end
|
91
64
|
|
92
65
|
it 'create a background job queuer' do
|
93
|
-
@instance.
|
66
|
+
expect(@instance).to respond_to(:enqueue_avatar_background_job)
|
94
67
|
end
|
95
68
|
|
96
69
|
it 'create a trigger interrogator' do
|
97
|
-
@instance.
|
70
|
+
expect(@instance).to respond_to(:enqueue_avatar_background_job?)
|
98
71
|
end
|
99
|
-
|
100
72
|
end
|
101
73
|
end
|
102
|
-
|
103
74
|
end
|
@@ -1,87 +1,221 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'support/backend_constants'
|
3
|
+
require 'support/mock_worker'
|
2
4
|
|
3
5
|
describe Support::Backends do
|
4
|
-
let(:
|
6
|
+
let(:mock_module) { Module.new }
|
5
7
|
|
6
8
|
before do
|
7
|
-
|
9
|
+
mock_module.send :include, Support::Backends
|
8
10
|
end
|
9
11
|
|
10
12
|
describe 'enumerating available backends' do
|
11
13
|
it 'detects GirlFriday' do
|
12
|
-
|
14
|
+
expect(mock_module.available_backends).to include(:girl_friday)
|
13
15
|
end
|
14
16
|
|
15
17
|
it 'detects Delayed::Job' do
|
16
|
-
|
18
|
+
expect(mock_module.available_backends).to include(:delayed_job)
|
17
19
|
end
|
18
20
|
|
19
21
|
it 'detects Resque' do
|
20
|
-
|
22
|
+
expect(mock_module.available_backends).to include(:resque)
|
21
23
|
end
|
22
24
|
|
23
25
|
it 'detects Qu' do
|
24
|
-
|
26
|
+
expect(mock_module.available_backends).to include(:qu)
|
25
27
|
end
|
26
28
|
|
27
29
|
it 'detects Sidekiq' do
|
28
|
-
|
30
|
+
expect(mock_module.available_backends).to include(:sidekiq)
|
29
31
|
end
|
30
32
|
|
31
33
|
it 'detects QC' do
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'detects Immediate' do
|
36
|
-
test_module.available_backends.should include(:immediate)
|
34
|
+
expect(mock_module.available_backends).to include(:qc)
|
37
35
|
end
|
38
36
|
end
|
39
37
|
|
40
38
|
describe 'setting backend' do
|
41
39
|
it 'using #backend=' do
|
42
|
-
|
43
|
-
expect(
|
40
|
+
mock_module.backend = :delayed_job
|
41
|
+
expect(mock_module.backend).to eql(:delayed_job)
|
44
42
|
end
|
45
43
|
|
46
44
|
it 'using #backend' do
|
47
|
-
|
48
|
-
expect(
|
45
|
+
mock_module.backend(:delayed_job)
|
46
|
+
expect(mock_module.backend).to eql(:delayed_job)
|
49
47
|
end
|
50
48
|
|
51
49
|
it 'allows passing of queue_options' do
|
52
|
-
|
53
|
-
expect(
|
50
|
+
mock_module.backend(:delayed_job, :queue => :awesome_queue)
|
51
|
+
expect(mock_module.queue_options).to eql({:queue => :awesome_queue})
|
54
52
|
end
|
55
53
|
end
|
56
54
|
|
57
|
-
describe '
|
55
|
+
describe 'auto detect backends' do
|
58
56
|
before do
|
59
|
-
|
57
|
+
mock_module.instance_variable_set('@backend', nil)
|
60
58
|
end
|
61
59
|
|
62
60
|
it 'sets the backend to immediate if none available' do
|
63
61
|
suppress_warnings do
|
64
|
-
|
65
|
-
expect(
|
62
|
+
mock_module.stubs(:available_backends).returns([])
|
63
|
+
expect(mock_module.backend).to eql(:immediate)
|
66
64
|
end
|
67
65
|
end
|
68
66
|
|
69
67
|
it 'sets a backend automatically if only one is available' do
|
70
|
-
|
71
|
-
|
68
|
+
mock_module.stubs(:available_backends).returns([ :qu ])
|
69
|
+
expect(mock_module.backend).to eql(:qu)
|
72
70
|
end
|
73
71
|
|
74
72
|
it 'raises an error if more than one backend is available' do
|
75
|
-
|
73
|
+
mock_module.stubs(:available_backends).returns([:qu, :resque])
|
76
74
|
expect {
|
77
|
-
|
78
|
-
}.to raise_error(CarrierWave::Backgrounder::
|
75
|
+
mock_module.backend
|
76
|
+
}.to raise_error(CarrierWave::Backgrounder::TooManyBackendsAvailableError)
|
79
77
|
end
|
80
78
|
|
81
79
|
it 'does not clobber a manually set backend' do
|
82
|
-
|
83
|
-
|
80
|
+
mock_module.backend = :not_a_backend
|
81
|
+
expect(mock_module.backend).to eql(:not_a_backend)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#enqueue_for_backend' do
|
86
|
+
let!(:worker) { MockWorker.new('FakeClass', 1, :image) }
|
87
|
+
|
88
|
+
context 'delayed_job' do
|
89
|
+
before do
|
90
|
+
@mock_worker = Class.new do
|
91
|
+
def self.perform(*args); new(*args).perform; end
|
92
|
+
end
|
93
|
+
|
94
|
+
MockWorker.expects(:new).returns(worker)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'defaults the queue name to nil if none passed to #backend' do
|
98
|
+
mock_module.backend :delayed_job
|
99
|
+
Delayed::Job.expects(:enqueue).with(worker, :queue => nil)
|
100
|
+
mock_module.enqueue_for_backend MockWorker, 'FakeClass', 1, :image
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'sets the queue name to the queue name passed to #backend' do
|
104
|
+
mock_module.backend :delayed_job, :queue => :awesome_queue
|
105
|
+
Delayed::Job.expects(:enqueue).with(worker, :queue => :awesome_queue)
|
106
|
+
mock_module.enqueue_for_backend MockWorker, 'FakeClass', 1, :image
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'resque' do
|
111
|
+
let(:args) { [MockWorker, 'FakeClass', 1, :image] }
|
112
|
+
|
113
|
+
before do
|
114
|
+
Resque.expects(:enqueue).with(*args)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'sets a variable with the queue name, defaults to :carrierwave' do
|
118
|
+
mock_module.backend :resque
|
119
|
+
mock_module.enqueue_for_backend(*args)
|
120
|
+
expect(MockWorker.instance_variable_get '@queue').to eql(:carrierwave)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'sets a variable to the queue name passed to #backend' do
|
124
|
+
mock_module.backend :resque, :queue => :awesome_queue
|
125
|
+
mock_module.enqueue_for_backend(*args)
|
126
|
+
expect(MockWorker.instance_variable_get '@queue').to eql(:awesome_queue)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'sidekiq' do
|
131
|
+
let(:args) { ['FakeClass', 1, :image] }
|
132
|
+
|
133
|
+
it 'invokes client_push on the class with passed args' do
|
134
|
+
MockSidekiqWorker.expects(:client_push).with({ 'class' => MockSidekiqWorker, 'args' => args })
|
135
|
+
mock_module.backend :sidekiq
|
136
|
+
mock_module.enqueue_for_backend(MockSidekiqWorker, *args)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'invokes client_push and includes the options passed to backend' do
|
140
|
+
MockSidekiqWorker.expects(:client_push).with({ 'class' => MockSidekiqWorker,
|
141
|
+
'retry' => false,
|
142
|
+
'timeout' => 60,
|
143
|
+
'queue' => :awesome_queue,
|
144
|
+
'args' => args })
|
145
|
+
options = {:retry => false, :timeout => 60, :queue => :awesome_queue}
|
146
|
+
mock_module.backend :sidekiq, options
|
147
|
+
mock_module.enqueue_for_backend(MockSidekiqWorker, *args)
|
148
|
+
end
|
84
149
|
end
|
150
|
+
|
151
|
+
context 'girl_friday' do
|
152
|
+
let(:args) { [MockWorker, 'FakeClass', 1, :image] }
|
153
|
+
|
154
|
+
it 'instantiates a GirlFriday work queue if one does not exist' do
|
155
|
+
mock_module.backend :girl_friday
|
156
|
+
GirlFriday::WorkQueue.expects(:new).with(:carrierwave, {}).returns([])
|
157
|
+
mock_module.enqueue_for_backend(*args)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'instantiates a GirlFriday work queue passing the args to the queue' do
|
161
|
+
mock_module.backend :girl_friday, :queue => :awesome_queue, :size => 3
|
162
|
+
GirlFriday::WorkQueue.expects(:new).with(:awesome_queue, {:size => 3}).returns([])
|
163
|
+
mock_module.enqueue_for_backend(*args)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'does not instantiate a GirlFriday work queue if one exists' do
|
167
|
+
mock_module.backend :girl_friday
|
168
|
+
mock_module.instance_variable_set('@girl_friday_queue', [])
|
169
|
+
GirlFriday::WorkQueue.expects(:new).never
|
170
|
+
mock_module.enqueue_for_backend(*args)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'add a worker to the girl_friday queue' do
|
174
|
+
expected = [{ :worker => MockWorker.new('FakeClass', 1, :image) }]
|
175
|
+
mock_module.backend :girl_friday
|
176
|
+
mock_module.instance_variable_set('@girl_friday_queue', [])
|
177
|
+
mock_module.enqueue_for_backend(*args)
|
178
|
+
expect(mock_module.instance_variable_get '@girl_friday_queue').to eql(expected)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'qu' do
|
183
|
+
let(:args) { [MockWorker, 'FakeClass', 1, :image] }
|
184
|
+
before do
|
185
|
+
Qu.expects(:enqueue).with(*args)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'sets a variable with the queue name, defaults to :carrierwave' do
|
189
|
+
mock_module.backend :qu
|
190
|
+
mock_module.enqueue_for_backend(*args)
|
191
|
+
expect(MockWorker.instance_variable_get '@queue').to eql(:carrierwave)
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'sets a variable to the queue name passed to #backend' do
|
195
|
+
mock_module.backend :qu, :queue => :awesome_queue
|
196
|
+
mock_module.enqueue_for_backend(*args)
|
197
|
+
expect(MockWorker.instance_variable_get '@queue').to eql(:awesome_queue)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'qc' do
|
202
|
+
it 'calls enqueue with the passed args' do
|
203
|
+
QC.expects(:enqueue).with("MockWorker.perform", 'FakeClass', 1, 'image')
|
204
|
+
mock_module.backend :qc
|
205
|
+
mock_module.enqueue_for_backend(MockWorker, 'FakeClass', 1, :image)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'immediate' do
|
210
|
+
it 'instantiates a worker passing the args and calls perform' do
|
211
|
+
worker = mock('Worker')
|
212
|
+
MockWorker.expects(:new).with('FakeClass', 1, :image).returns(worker)
|
213
|
+
worker.expects(:perform)
|
214
|
+
mock_module.backend :immediate
|
215
|
+
mock_module.enqueue_for_backend(MockWorker, 'FakeClass', 1, :image)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
85
219
|
end
|
86
220
|
end
|
87
221
|
|
File without changes
|
@@ -5,10 +5,9 @@ require 'backgrounder/workers/process_asset'
|
|
5
5
|
describe CarrierWave::Workers::ProcessAsset do
|
6
6
|
let(:worker_class) { CarrierWave::Workers::ProcessAsset }
|
7
7
|
let(:user) { mock('User') }
|
8
|
-
let(:image) { mock('UserAsset') }
|
9
8
|
let!(:worker) { worker_class.new(user, '22', :image) }
|
10
9
|
|
11
|
-
|
10
|
+
describe ".perform" do
|
12
11
|
it 'creates a new instance and calls perform' do
|
13
12
|
args = [user, '22', :image]
|
14
13
|
worker_class.expects(:new).with(*args).returns(worker)
|
@@ -18,29 +17,54 @@ describe CarrierWave::Workers::ProcessAsset do
|
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
21
|
-
|
22
|
-
|
20
|
+
describe "#perform" do
|
21
|
+
let(:image) { mock('UserAsset') }
|
22
|
+
|
23
|
+
before do
|
23
24
|
user.expects(:find).with('22').returns(user).once
|
24
25
|
user.expects(:image).once.returns(image)
|
25
26
|
user.expects(:process_image_upload=).with(true).once
|
26
|
-
|
27
27
|
image.expects(:recreate_versions!).once.returns(true)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'processes versions with image_processing column' do
|
28
31
|
user.expects(:respond_to?).with(:image_processing).once.returns(true)
|
29
|
-
user.expects(:
|
30
|
-
user.expects(:save!)
|
32
|
+
user.expects(:update_attribute).with(:image_processing, nil).once
|
31
33
|
worker.perform
|
32
34
|
end
|
33
35
|
|
34
36
|
it 'processes versions without image_processing column' do
|
35
|
-
user.expects(:find).with('22').returns(user).once
|
36
|
-
user.expects(:image).once.returns(image)
|
37
|
-
user.expects(:process_image_upload=).with(true).once
|
38
|
-
|
39
|
-
image.expects(:recreate_versions!).once.returns(true)
|
40
37
|
user.expects(:respond_to?).with(:image_processing).once.returns(false)
|
41
|
-
user.expects(:
|
42
|
-
user.expects(:save!).never
|
38
|
+
user.expects(:update_attribute).never
|
43
39
|
worker.perform
|
44
40
|
end
|
45
41
|
end
|
42
|
+
|
43
|
+
describe '#perform with args' do
|
44
|
+
let(:admin) { mock('Admin') }
|
45
|
+
let(:avatar) { mock('AdminAsset') }
|
46
|
+
let(:worker) { worker_class.new }
|
47
|
+
|
48
|
+
before do
|
49
|
+
admin.expects(:find).with('23').returns(admin).once
|
50
|
+
admin.expects(:avatar).once.returns(avatar)
|
51
|
+
admin.expects(:process_avatar_upload=).with(true).once
|
52
|
+
admin.expects(:respond_to?).with(:avatar_processing).once.returns(false)
|
53
|
+
avatar.expects(:recreate_versions!).once.returns(true)
|
54
|
+
|
55
|
+
worker.perform admin, '23', :avatar
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'sets klass' do
|
59
|
+
expect(worker.klass).to eql(admin)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'sets column' do
|
63
|
+
expect(worker.id).to eql('23')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'sets id' do
|
67
|
+
expect(worker.column).to eql(:avatar)
|
68
|
+
end
|
69
|
+
end
|
46
70
|
end
|
@@ -3,35 +3,87 @@ require 'spec_helper'
|
|
3
3
|
require 'backgrounder/workers/store_asset'
|
4
4
|
|
5
5
|
describe CarrierWave::Workers::StoreAsset do
|
6
|
+
let(:fixtures_path) { File.expand_path('../fixtures/images', __FILE__) }
|
6
7
|
let(:worker_class) { CarrierWave::Workers::StoreAsset }
|
7
|
-
let(:user)
|
8
|
-
let(:image) { mock('UserAsset') }
|
8
|
+
let(:user) { mock('User') }
|
9
9
|
let!(:worker) { worker_class.new(user, '22', :image) }
|
10
10
|
|
11
|
-
|
11
|
+
describe ".perform" do
|
12
12
|
it 'creates a new instance and calls perform' do
|
13
13
|
args = [user, '22', :image]
|
14
14
|
worker_class.expects(:new).with(*args).returns(worker)
|
15
15
|
worker_class.any_instance.expects(:perform)
|
16
|
-
|
17
16
|
worker_class.perform(*args)
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
user.expects(:image_tmp).once.returns('test.jpg')
|
26
|
-
user.expects(:image).once.returns(image)
|
20
|
+
describe "#perform" do
|
21
|
+
let(:image) { mock('UserAsset') }
|
22
|
+
|
23
|
+
before do
|
27
24
|
image.expects(:root).once.returns(File.expand_path('..', __FILE__))
|
28
25
|
image.expects(:cache_dir).once.returns('fixtures')
|
26
|
+
user.expects(:image_tmp).twice.returns('images/test.jpg')
|
27
|
+
user.expects(:find).with('22').once.returns(user)
|
28
|
+
user.expects(:image).once.returns(image)
|
29
29
|
user.expects(:process_image_upload=).with(true).once
|
30
30
|
user.expects(:image=).once
|
31
31
|
user.expects(:image_tmp=).with(nil).once
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'removes tmp directory on success' do
|
35
|
+
FileUtils.expects(:rm_r).with(fixtures_path, :force => true).once
|
32
36
|
user.expects(:save!).once.returns(true)
|
37
|
+
worker.perform
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'does not remove the tmp directory if save! fails' do
|
41
|
+
FileUtils.expects(:rm_r).never
|
42
|
+
user.expects(:save!).once.returns(false)
|
43
|
+
worker.perform
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'sets the cache_path' do
|
47
|
+
user.expects(:save!).once.returns(false)
|
48
|
+
worker.perform
|
49
|
+
expect(worker.cache_path).to eql(fixtures_path + '/test.jpg')
|
50
|
+
end
|
33
51
|
|
52
|
+
it 'sets the tmp_directory' do
|
53
|
+
user.expects(:save!).once.returns(false)
|
34
54
|
worker.perform
|
55
|
+
expect(worker.tmp_directory).to eql(fixtures_path)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#perform with args' do
|
60
|
+
let(:admin) { mock('Admin') }
|
61
|
+
let(:image) { mock('AdminAsset') }
|
62
|
+
let(:worker) { worker_class.new }
|
63
|
+
|
64
|
+
before do
|
65
|
+
image.expects(:root).once.returns(File.expand_path('..', __FILE__))
|
66
|
+
image.expects(:cache_dir).once.returns('fixtures')
|
67
|
+
admin.expects(:avatar_tmp).twice.returns('images/test.jpg')
|
68
|
+
admin.expects(:find).with('23').once.returns(admin)
|
69
|
+
admin.expects(:avatar).once.returns(image)
|
70
|
+
admin.expects(:process_avatar_upload=).with(true).once
|
71
|
+
admin.expects(:avatar=).once
|
72
|
+
admin.expects(:avatar_tmp=).with(nil).once
|
73
|
+
admin.expects(:save!).once.returns(false)
|
74
|
+
worker.perform admin, '23', :avatar
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'sets klass' do
|
78
|
+
expect(worker.klass).to eql(admin)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'sets column' do
|
82
|
+
expect(worker.id).to eql('23')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'sets id' do
|
86
|
+
expect(worker.column).to eql(:avatar)
|
35
87
|
end
|
36
88
|
end
|
37
|
-
end
|
89
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Fixture module declarations for backend detection testing
|
2
2
|
|
3
3
|
module GirlFriday
|
4
|
+
class WorkQueue
|
5
|
+
end
|
4
6
|
end
|
5
7
|
|
6
8
|
module Delayed
|
@@ -15,6 +17,9 @@ module Qu
|
|
15
17
|
end
|
16
18
|
|
17
19
|
module Sidekiq
|
20
|
+
module Client
|
21
|
+
end
|
22
|
+
|
18
23
|
module Worker
|
19
24
|
def self.included(base)
|
20
25
|
base.extend(ClassMethods)
|
@@ -23,6 +28,9 @@ module Sidekiq
|
|
23
28
|
module ClassMethods
|
24
29
|
def sidekiq_options(opts = {})
|
25
30
|
end
|
31
|
+
|
32
|
+
def client_push(item)
|
33
|
+
end
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class MockWorker < Struct.new(:klass, :id, :column)
|
2
|
+
def self.perform(*args)
|
3
|
+
new(*args).perform
|
4
|
+
end
|
5
|
+
|
6
|
+
def perform(*args)
|
7
|
+
set_args(*args) unless args.empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
def set_args(klass, id, column)
|
11
|
+
self.klass, self.id, self.column = klass, id, column
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class MockSidekiqWorker < MockWorker
|
16
|
+
include Sidekiq::Worker
|
17
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave_backgrounder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: carrierwave
|
@@ -84,6 +84,7 @@ extra_rdoc_files: []
|
|
84
84
|
files:
|
85
85
|
- .gitignore
|
86
86
|
- .rspec
|
87
|
+
- .travis.yml
|
87
88
|
- CHANGELOG.md
|
88
89
|
- Gemfile
|
89
90
|
- README.md
|
@@ -105,13 +106,15 @@ files:
|
|
105
106
|
- spec/backgrounder/orm/activemodel_spec.rb
|
106
107
|
- spec/backgrounder/orm/base_spec.rb
|
107
108
|
- spec/backgrounder/support/backends_spec.rb
|
108
|
-
- spec/backgrounder/workers/fixtures/test.jpg
|
109
|
+
- spec/backgrounder/workers/fixtures/images/test.jpg
|
109
110
|
- spec/backgrounder/workers/process_asset_spec.rb
|
110
111
|
- spec/backgrounder/workers/store_asset_spec.rb
|
111
112
|
- spec/spec_helper.rb
|
112
113
|
- spec/support/backend_constants.rb
|
113
|
-
|
114
|
-
|
114
|
+
- spec/support/mock_worker.rb
|
115
|
+
homepage: https://github.com/lardawge/carrierwave_backgrounder
|
116
|
+
licenses:
|
117
|
+
- MIT
|
115
118
|
post_install_message:
|
116
119
|
rdoc_options: []
|
117
120
|
require_paths:
|
@@ -124,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
124
127
|
version: '0'
|
125
128
|
segments:
|
126
129
|
- 0
|
127
|
-
hash: -
|
130
|
+
hash: -2596358502417703338
|
128
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
132
|
none: false
|
130
133
|
requirements:
|
@@ -133,20 +136,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
136
|
version: '0'
|
134
137
|
segments:
|
135
138
|
- 0
|
136
|
-
hash: -
|
139
|
+
hash: -2596358502417703338
|
137
140
|
requirements: []
|
138
|
-
rubyforge_project:
|
141
|
+
rubyforge_project:
|
139
142
|
rubygems_version: 1.8.24
|
140
143
|
signing_key:
|
141
144
|
specification_version: 3
|
142
145
|
summary: Offload CarrierWave's image processing and storage to a background process
|
143
|
-
using Delayed Job
|
146
|
+
using Delayed Job, Resque, Sidekiq, Qu, Queue Classic or Girl Friday
|
144
147
|
test_files:
|
145
148
|
- spec/backgrounder/orm/activemodel_spec.rb
|
146
149
|
- spec/backgrounder/orm/base_spec.rb
|
147
150
|
- spec/backgrounder/support/backends_spec.rb
|
148
|
-
- spec/backgrounder/workers/fixtures/test.jpg
|
151
|
+
- spec/backgrounder/workers/fixtures/images/test.jpg
|
149
152
|
- spec/backgrounder/workers/process_asset_spec.rb
|
150
153
|
- spec/backgrounder/workers/store_asset_spec.rb
|
151
154
|
- spec/spec_helper.rb
|
152
155
|
- spec/support/backend_constants.rb
|
156
|
+
- spec/support/mock_worker.rb
|