Commit b5ffea8f155baa1f898a45485c0770cbc000e1c7

Authored by Daniela Feitosa
Committed by Antonio Terceiro
1 parent d5ddc762

Upload of files done in background

* Added 'thumbnails_processed' to articles and images
  * Added images to be displayed when the uploaded were not processed yet

(ActionItem1661)
app/models/image.rb
... ... @@ -16,4 +16,7 @@ class Image < ActiveRecord::Base
16 16 :max_size => 500.kilobytes # remember to update validate message below
17 17  
18 18 validates_attachment :size => N_("%{fn} of uploaded file was larger than the maximum size of 500.0 KB")
  19 +
  20 + delay_attachment_fu_thumbnails
  21 +
19 22 end
... ...
app/models/uploaded_file.rb
... ... @@ -34,6 +34,8 @@ class UploadedFile < Article
34 34  
35 35 validates_attachment :size => N_("%{fn} of uploaded file was larger than the maximum size of 5.0 MB")
36 36  
  37 + delay_attachment_fu_thumbnails
  38 +
37 39 def icon_name
38 40 self.image? ? public_filename(:icon) : self.content_type.gsub('/', '-')
39 41 end
... ... @@ -60,7 +62,6 @@ class UploadedFile < Article
60 62 File.read(self.full_filename)
61 63 end
62 64  
63   -
64 65 def to_html(options = {})
65 66 article = self
66 67 if image?
... ...
db/migrate/20100831193450_add_thumbnails_processed_to_articles.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class AddThumbnailsProcessedToArticles < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :articles, :thumbnails_processed, :boolean, :default => false
  4 + add_column :article_versions, :thumbnails_processed, :boolean, :default => false
  5 + end
  6 +
  7 + def self.down
  8 + remove_column :articles, :thumbnails_processed
  9 + remove_column :article_versions, :thumbnails_processed
  10 + end
  11 +end
... ...
db/migrate/20100901203836_add_thumbnails_processed_to_image.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class AddThumbnailsProcessedToImage < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :images, :thumbnails_processed, :boolean, :default => false
  4 + end
  5 +
  6 + def self.down
  7 + remove_column :images, :thumbnails_processed, :boolean, :default => false
  8 + end
  9 +end
... ...
db/schema.rb
... ... @@ -9,7 +9,7 @@
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11  
12   -ActiveRecord::Schema.define(:version => 20100823190348) do
  12 +ActiveRecord::Schema.define(:version => 20100901203836) do
13 13  
14 14 create_table "article_versions", :force => true do |t|
15 15 t.integer "article_id"
... ... @@ -46,6 +46,7 @@ ActiveRecord::Schema.define(:version =&gt; 20100823190348) do
46 46 t.string "source"
47 47 t.boolean "highlighted", :default => false
48 48 t.string "external_link"
  49 + t.boolean "thumbnails_processed", :default => false
49 50 end
50 51  
51 52 create_table "articles", :force => true do |t|
... ... @@ -81,6 +82,7 @@ ActiveRecord::Schema.define(:version =&gt; 20100823190348) do
81 82 t.string "source"
82 83 t.boolean "highlighted", :default => false
83 84 t.string "external_link"
  85 + t.boolean "thumbnails_processed", :default => false
84 86 end
85 87  
86 88 create_table "articles_categories", :id => false, :force => true do |t|
... ... @@ -243,6 +245,7 @@ ActiveRecord::Schema.define(:version =&gt; 20100823190348) do
243 245 t.integer "size"
244 246 t.integer "width"
245 247 t.integer "height"
  248 + t.boolean "thumbnails_processed", :default => false
246 249 end
247 250  
248 251 create_table "inputs", :force => true do |t|
... ...
public/images/icons-app/image-loading-big.png 0 → 100644

10.7 KB

public/images/icons-app/image-loading-display.png 0 → 100644

42.2 KB

public/images/icons-app/image-loading-icon.png 0 → 100644

960 Bytes

public/images/icons-app/image-loading-minor.png 0 → 100644

3 KB

public/images/icons-app/image-loading-portrait.png 0 → 100644

4.03 KB

public/images/icons-app/image-loading-slideshow.png 0 → 100644

18.4 KB

public/images/icons-app/image-loading-thumb.png 0 → 100644

6.9 KB

test/functional/cms_controller_test.rb
... ... @@ -923,8 +923,10 @@ class CmsControllerTest &lt; Test::Unit::TestCase
923 923 :parent_id => f.id,
924 924 :article => {:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')}
925 925  
926   - assert File.exists?(assigns(:article).icon_name)
927   - assigns(:article).destroy
  926 + process_delayed_job_queue
  927 + file = profile.articles.find_by_name('rails.png')
  928 + assert File.exists?(file.icon_name)
  929 + file.destroy
928 930 end
929 931  
930 932 should 'create icon upload file' do
... ... @@ -932,8 +934,10 @@ class CmsControllerTest &lt; Test::Unit::TestCase
932 934 :type => UploadedFile.name,
933 935 :article => {:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')}
934 936  
935   - assert File.exists?(assigns(:article).icon_name)
936   - assigns(:article).destroy
  937 + process_delayed_job_queue
  938 + file = profile.articles.find_by_name('rails.png')
  939 + assert File.exists?(file.icon_name)
  940 + file.destroy
937 941 end
938 942  
939 943 should 'record when coming from public view on upload files' do
... ... @@ -1052,10 +1056,20 @@ class CmsControllerTest &lt; Test::Unit::TestCase
1052 1056  
1053 1057 should 'display list of images' do
1054 1058 file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'))
  1059 + process_delayed_job_queue
  1060 + get :media_listing, :profile => profile.identifier
  1061 +
  1062 + assert_tag :tag => 'div', :attributes => { :id => 'media-listing-images' }, :descendant => { :tag => 'img', :attributes => {:src => /rails.png/}}
  1063 + end
  1064 +
  1065 + should 'display loading image if not processed yet' do
  1066 + file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'))
1055 1067 get :media_listing, :profile => profile.identifier
1056   - assert_tag :tag => 'div', :attributes => { :id => 'media-listing-images' }, :descendant => { :tag => 'img', :attributes => {:src => /#{file.name}/}}
  1068 +
  1069 + assert_tag :tag => 'div', :attributes => { :id => 'media-listing-images' }, :descendant => { :tag => 'img', :attributes => {:src => /image-loading-thumb.png/}}
1057 1070 end
1058 1071  
  1072 +
1059 1073 should 'display list of documents' do
1060 1074 file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'))
1061 1075 get :media_listing, :profile => profile.identifier
... ... @@ -1265,4 +1279,19 @@ class CmsControllerTest &lt; Test::Unit::TestCase
1265 1279 assert_template 'edit'
1266 1280 end
1267 1281  
  1282 + should 'create thumbnails for images with delayed_job' do
  1283 + post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/rails.png', 'image/png'), fixture_file_upload('/files/test.txt', 'text/plain')]
  1284 + file_1 = profile.articles.find_by_path('rails.png')
  1285 + file_2 = profile.articles.find_by_path('test.txt')
  1286 +
  1287 + process_delayed_job_queue
  1288 +
  1289 + UploadedFile.attachment_options[:thumbnails].each do |suffix, size|
  1290 + assert File.exists?(UploadedFile.find(file_1.id).public_filename(suffix))
  1291 + assert !File.exists?(UploadedFile.find(file_2.id).public_filename(suffix))
  1292 + end
  1293 + file_1.destroy
  1294 + file_2.destroy
  1295 + end
  1296 +
1268 1297 end
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -791,6 +791,52 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
791 791 assert_equal 2, assigns(:images).size
792 792 end
793 793  
  794 + should 'display default image in the slideshow if thumbnails were not processed' do
  795 + @controller.stubs(:per_page).returns(1)
  796 + folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery')
  797 +
  798 + image1 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'))
  799 +
  800 + get :view_page, :profile => profile.identifier, :page => folder.explode_path, :slideshow => true
  801 +
  802 + assert_tag :tag => 'img', :attributes => {:src => /\/images\/icons-app\/image-loading-display.png/}
  803 + end
  804 +
  805 + should 'display thumbnail image in the slideshow if thumbnails were processed' do
  806 + @controller.stubs(:per_page).returns(1)
  807 + folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery')
  808 +
  809 + image1 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'))
  810 +
  811 + process_delayed_job_queue
  812 + get :view_page, :profile => profile.identifier, :page => folder.explode_path, :slideshow => true
  813 +
  814 + assert_tag :tag => 'img', :attributes => {:src => /other-pic_display.jpg/}
  815 + end
  816 +
  817 + should 'display default image in gallery if thumbnails were not processed' do
  818 + @controller.stubs(:per_page).returns(1)
  819 + folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery')
  820 +
  821 + image1 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'))
  822 +
  823 + get :view_page, :profile => profile.identifier, :page => folder.explode_path
  824 +
  825 + assert_tag :tag => 'img', :attributes => {:src => /\/images\/icons-app\/image-loading-thumb.png/}
  826 + end
  827 +
  828 + should 'display thumbnail image in gallery if thumbnails were processed' do
  829 + @controller.stubs(:per_page).returns(1)
  830 + folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery')
  831 +
  832 + image1 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'))
  833 +
  834 + process_delayed_job_queue
  835 + get :view_page, :profile => profile.identifier, :page => folder.explode_path
  836 +
  837 + assert_tag :tag => 'img', :attributes => {:src => /other-pic_thumb.jpg/}
  838 + end
  839 +
794 840 should 'display source from article' do
795 841 profile.articles << TextileArticle.new(:name => "Article one", :profile => profile, :source => 'http://www.original-source.invalid')
796 842 get :view_page, :profile => profile.identifier, :page => ['article-one']
... ...
test/functional/search_controller_test.rb
... ... @@ -562,6 +562,8 @@ class SearchControllerTest &lt; Test::Unit::TestCase
562 562 cat = Category.create!(:name => 'category2', :environment => Environment.default, :parent => parent,
563 563 :image_builder => {:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')}
564 564 )
  565 +
  566 + process_delayed_job_queue
565 567 get :category_index, :category_path => [ 'category1', 'category2' ], :query => 'teste'
566 568 assert_tag :tag => 'img', :attributes => { :src => /rails_thumb\.png/ }
567 569 end
... ...
test/unit/image_test.rb
... ... @@ -3,6 +3,11 @@ require File.dirname(__FILE__) + &#39;/../test_helper&#39;
3 3 class ImageTest < Test::Unit::TestCase
4 4 fixtures :images
5 5  
  6 + def setup
  7 + @profile = create_user('testinguser').person
  8 + end
  9 + attr_reader :profile
  10 +
6 11 should 'have thumbnails options' do
7 12 [:big, :thumb, :portrait, :minor, :icon].each do |option|
8 13 assert Image.attachment_options[:thumbnails].include?(option), "should have #{option}"
... ... @@ -16,4 +21,67 @@ class ImageTest &lt; Test::Unit::TestCase
16 21 assert_match /#{Image.max_size.to_humanreadable}/, image.errors[:size]
17 22 end
18 23  
  24 + should 'create thumbnails after processing jobs' do
  25 + file = Image.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :owner => profile)
  26 +
  27 + process_delayed_job_queue
  28 + Image.attachment_options[:thumbnails].each do |suffix, size|
  29 + assert File.exists?(Image.find(file.id).public_filename(suffix))
  30 + end
  31 + file.destroy
  32 + end
  33 +
  34 + should 'set thumbnails_processed to true after creating thumbnails' do
  35 + file = Image.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :owner => profile)
  36 +
  37 + process_delayed_job_queue
  38 +
  39 + assert Image.find(file.id).thumbnails_processed
  40 + file.destroy
  41 + end
  42 +
  43 + should 'have thumbnails_processed attribute' do
  44 + assert Image.new.respond_to?(:thumbnails_processed)
  45 + end
  46 +
  47 + should 'return false by default in thumbnails_processed' do
  48 + assert !Image.new.thumbnails_processed
  49 + end
  50 +
  51 + should 'set thumbnails_processed to true' do
  52 + file = Image.new
  53 + file.thumbnails_processed = true
  54 +
  55 + assert file.thumbnails_processed
  56 + end
  57 +
  58 + should 'have a default image if thumbnails were not processed' do
  59 + file = Image.new
  60 + assert_equal '/images/icons-app/image-loading-thumb.png', file.public_filename(:thumb)
  61 + end
  62 +
  63 + should 'return image thumbnail if thumbnails were processed' do
  64 + file = Image.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :owner => profile)
  65 + process_delayed_job_queue
  66 +
  67 + assert_match(/rails_thumb.png/, Image.find(file.id).public_filename(:thumb))
  68 +
  69 + file.destroy
  70 + end
  71 +
  72 + should 'store width and height after processing' do
  73 + file = Image.create!(:owner => profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'))
  74 + file.create_thumbnails
  75 +
  76 + file = Image.find(file.id)
  77 + assert_equal [50, 64], [file.width, file.height]
  78 + end
  79 +
  80 + should 'have a loading image to each size of thumbnails' do
  81 + Image.attachment_options[:thumbnails].each do |suffix, size|
  82 + image = RAILS_ROOT + '/public/images/icons-app/image-loading-%s.png' % suffix
  83 + assert File.exists?(image)
  84 + end
  85 + end
  86 +
19 87 end
... ...
test/unit/products_block_test.rb
... ... @@ -136,4 +136,27 @@ class ProductsBlockTest &lt; ActiveSupport::TestCase
136 136  
137 137 assert_tag_in_string footer, :tag => 'a', :attributes => { :href => /\/catalog\/testenterprise$/ }, :content => 'View all products'
138 138 end
  139 +
  140 + should 'display the default minor image if thumbnails were not processed' do
  141 + enterprise = Enterprise.create!(:name => 'testenterprise', :identifier => 'testenterprise')
  142 + enterprise.products.create!(:name => 'product', :product_category => @product_category, :image_builder => { :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')})
  143 +
  144 + block.expects(:products).returns(enterprise.products)
  145 +
  146 + content = block.content
  147 +
  148 + assert_tag_in_string content, :tag => 'a', :attributes => { :style => /image-loading-minor.png/ }
  149 + end
  150 +
  151 + should 'display the thumbnail image if thumbnails were processed' do
  152 + enterprise = Enterprise.create!(:name => 'testenterprise', :identifier => 'testenterprise')
  153 + enterprise.products.create!(:name => 'product', :product_category => @product_category, :image_builder => { :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')})
  154 +
  155 + process_delayed_job_queue
  156 + block.expects(:products).returns(enterprise.products.reload)
  157 +
  158 + content = block.content
  159 + assert_tag_in_string content, :tag => 'a', :attributes => { :style => /rails_minor.png/ }
  160 + end
  161 +
139 162 end
... ...
test/unit/slideshow_block_test.rb
... ... @@ -82,6 +82,14 @@ class SlideshowBlockTest &lt; ActiveSupport::TestCase
82 82 assert_equal '/bli/slideshow.png', SlideshowBlock.new(:image_size => 'slideshow').public_filename_for(image)
83 83 end
84 84  
  85 + should 'display the default slideshow image if thumbnails were not processed' do
  86 + image = mock
  87 + image.expects(:public_filename).with('slideshow').returns('/images/icons-app/image-loading-slideshow.png')
  88 + File.expects(:exists?).with("#{Rails.root}/public/images/icons-app/image-loading-slideshow.png").returns(true)
  89 +
  90 + assert_equal '/images/icons-app/image-loading-slideshow.png', SlideshowBlock.new(:image_size => 'slideshow').public_filename_for(image)
  91 + end
  92 +
85 93 should 'fallback to existing size in case the requested size does not exist' do
86 94 block = SlideshowBlock.new(:image_size => 'slideshow')
87 95  
... ...
test/unit/uploaded_file_test.rb
... ... @@ -90,7 +90,8 @@ class UploadedFileTest &lt; Test::Unit::TestCase
90 90 f = fast_create(Folder, :name => 'test_folder', :profile_id => p.id)
91 91 file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent_id => f.id, :profile => p)
92 92  
93   - assert File.exists?(file.public_filename(:icon))
  93 + process_delayed_job_queue
  94 + assert File.exists?(UploadedFile.find(file.id).public_filename(:icon))
94 95 file.destroy
95 96 end
96 97  
... ... @@ -98,7 +99,8 @@ class UploadedFileTest &lt; Test::Unit::TestCase
98 99 p = create_user('test_user').person
99 100 file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => p)
100 101  
101   - assert File.exists?(file.public_filename(:icon))
  102 + process_delayed_job_queue
  103 + assert File.exists?(UploadedFile.find(file.id).public_filename(:icon))
102 104 file.destroy
103 105 end
104 106  
... ... @@ -156,4 +158,74 @@ class UploadedFileTest &lt; Test::Unit::TestCase
156 158 assert_nil upload.errors[:title]
157 159 end
158 160  
  161 + should 'create thumbnails after processing jobs' do
  162 + file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => profile)
  163 +
  164 + process_delayed_job_queue
  165 +
  166 + UploadedFile.attachment_options[:thumbnails].each do |suffix, size|
  167 + assert File.exists?(UploadedFile.find(file.id).public_filename(suffix))
  168 + end
  169 + file.destroy
  170 + end
  171 +
  172 + should 'set thumbnails_processed to true after creating thumbnails' do
  173 + file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => profile)
  174 +
  175 + process_delayed_job_queue
  176 +
  177 + assert UploadedFile.find(file.id).thumbnails_processed
  178 + file.destroy
  179 + end
  180 +
  181 + should 'have thumbnails_processed attribute' do
  182 + assert UploadedFile.new.respond_to?(:thumbnails_processed)
  183 + end
  184 +
  185 + should 'return false by default in thumbnails_processed' do
  186 + assert !UploadedFile.new.thumbnails_processed
  187 + end
  188 +
  189 + should 'set thumbnails_processed to true' do
  190 + file = UploadedFile.new
  191 + file.thumbnails_processed = true
  192 +
  193 + assert file.thumbnails_processed
  194 + end
  195 +
  196 + should 'have a default image if thumbnails were not processed' do
  197 + file = UploadedFile.new
  198 + assert_equal '/images/icons-app/image-loading-thumb.png', file.public_filename
  199 + end
  200 +
  201 + should 'return image thumbnail if thumbnails were processed' do
  202 + file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => profile)
  203 + process_delayed_job_queue
  204 +
  205 + assert_match(/rails_thumb.png/, UploadedFile.find(file.id).public_filename(:thumb))
  206 +
  207 + file.destroy
  208 + end
  209 +
  210 + should 'return the default thumbnail image as icon for images ' do
  211 + f = UploadedFile.new
  212 + f.expects(:image?).returns(true)
  213 + f.expects(:public_filename).with(:icon).returns('/path/to/file.xyz')
  214 + assert_equal '/path/to/file.xyz', f.icon_name
  215 + end
  216 +
  217 + should 'store width and height after processing' do
  218 + file = UploadedFile.create!(:profile => @profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'))
  219 + file.create_thumbnails
  220 +
  221 + file = UploadedFile.find(file.id)
  222 + assert_equal [50, 64], [file.width, file.height]
  223 + end
  224 +
  225 + should 'have a loading image to each size of thumbnails' do
  226 + UploadedFile.attachment_options[:thumbnails].each do |suffix, size|
  227 + image = RAILS_ROOT + '/public/images/icons-app/image-loading-%s.png' % suffix
  228 + assert File.exists?(image)
  229 + end
  230 + end
159 231 end
... ...