Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixtures with Paperclip

I'm using Paperclip to store documents, but I can't find how to create fixtures of them, I wrote this :

<% doc = Document.create(:asset => File.open(Rails.root.join('spec', 'assets', 'image.png'))) %>
<%= part_event_image %>:
  asset_file_name: <%= doc.asset_file_name %>
  asset_content_type: <%= doc.asset_content_type %>
  asset_file_size: <%= doc.asset_file_size %>
  asset_updated_at: <%= doc.asset_updated_at %>
  documentable: party (Event) %>
<% end %>

But one I ran it, the document exist in the database, but it's not stored.

Should I store the document myself (write the file) ? Or is there an other way ?

like image 931
Dorian Avatar asked Mar 15 '12 21:03

Dorian


2 Answers

You can do with fixture_file_upload

include ActionDispatch::TestProcess
Document.create(:asset => fixture_file_upload("#{Rails.root}/path/to/image.png", "image/png"))

or with factory girl

include ActionDispatch::TestProcess

FactoryGirl.define do
  factory :asset do
    asset { fixture_file_upload("#{Rails.root}/path/to/image.png", "image/png") }
  end
end
like image 136
m4tm4t Avatar answered Oct 02 '22 00:10

m4tm4t


Another approach is to define attribute value to yml and to prepare static file so that we can use it without uploading files via fixture_file_upload method on the fly during the test(= saves CPU resource).

1) Let's assume Music model has audio paperclip as follows:

class Music < ActiveRecord::Base
  has_attached_file :audio
  ...
end

2) define audio storage directory for testing only at config/environments/test.rb as:

MyApp::Application.configure do
  Paperclip::Attachment.default_options[:path] = ':rails_root/test/data/paperclip/:class/:attachment/:id_partition/:filename'
  ...
end

(E.g., audio file "sound_of_music.mp3" will be stored under test/data/paperclip/musics/audios/111/222/333/sound_of_music.mp3, where 111222333 is a music record id and 111/222/333 is an id_partiion part defined at 2) above.)

(NOTE: above definition for test impacts development/production storage path (I don't know why?) so that I needed to redefine another paths for dev & prod as follows at config/initializers/paperclip.rb:)

if Rails.env != 'test'
  Paperclip::Attachment.default_options[:path] = 'mount_prefix_for_your_app/:rails_env/:class/:attachment/:id_partition/:filename'
end

3) write test/fixtures/musics.yml as:

music01:
  title: 'sound of music'
  audio_file_name: sound_of_music.mp3
  ...

4) store actual mp3. Let's assume to upload from /tmp/sound_of_music.mp3 to the paperclip storage defined at 2) above via rails-console:

$ RAILS_ENV=test bundle exec rails console
> include ActionDispatch::TestProcess
> m = Music.find_by_title('sound of music')
> m.audio = fixture_file_upload("/tmp/sound_of_music.mp3", "audio/x-mpeg")
> m.save!

Above steps 1)..4) are preparation tasks before running test.

5) Now, we can use it at unit-test (or, model-test at rails-4) as:

class MusicTest < ActiveSupport::TestCase
  ...
  m = musics(:music01)
  assert File.exist?(m.audio.path)
  ...
like image 42
Fumisky Wells Avatar answered Oct 01 '22 22:10

Fumisky Wells