I want to test a model with a basic file upload which does not use a plugin (I think it was a bad idea at the time but know I have to deal with tons of existing documents).
The thing is that I want to test the size of the uploaded file, so I need to access to the temfile
attribute of file
which is a ActionDispatch::Http::UploadedFile
It works quite well in my controllers but I can't find how to make my factory pass.
Attachment Model:
attr_accessor :file # file_field_tag name
attr_accessible :file, :filename # store the filename in the db
before_save :upload_file
def upload_file
if self.file && File.size(self.file.tempfile) < 10.megabytes
puts self.file.class.inspect # see below
File.open("#{Rails.root.to_s}/files/" + self.filename.to_s, 'wb') do |f|
f.write(self.file.read)
end
ensure_file_presence
end
end
FactoryGirl Attachment:
FactoryGirl.define do
factory :attachment do
filename 'anyfile.txt'
file ActionDispatch::Http::UploadedFile.new(:tempfile => "#{Rails.root}/spec/fixtures/anyfile.txt", :filename => "anyfile.txt")
end
end
When I run tests, a FactoryGirl.build :attachment
will succeed but with a create
will fail.
Strange observation: I've displayed the self.file
class before the File.open and it is seen as a ActionDispatch::Http::UploadedFile
, then I have an error on self.file.read
: it has changed into a String.
puts self.file.class.inspect
=> ActionDispatch::Http::UploadedFile
f.write(self.file.read) => NoMethodError: undefined method `read' for #<String:0x007ff50f70f6a0>
I've read other posts that suggest I should use Rack::Test::UploadedFile
or fixture_file_upload
but I can't make it work, as the tempfile won't exists of any of these 2 solutions.
I see one issue. UpLoadedFile (:tempfile
) is expecting a File not a String. For you observation, it never changed into a String you defined it as a String. You need to surround it with a File.new()
as shown below. You need to put the file there before you try to run the test. Hope this helps!
FactoryGirl.define do
factory :attachment do
file ActionDispatch::Http::UploadedFile.new(:tempfile => File.new("#{Rails.root}/spec/fixtures/anyfile.txt"), :filename => "anyfile.txt")
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With