Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

My FactoryBot error is reoccurring with rack-test 0.8.2 #211

Closed
aebirim opened this issue Nov 21, 2017 · 13 comments · Fixed by #215
Closed

My FactoryBot error is reoccurring with rack-test 0.8.2 #211

aebirim opened this issue Nov 21, 2017 · 13 comments · Fixed by #215
Labels

Comments

@aebirim
Copy link

aebirim commented Nov 21, 2017

Stacktrace:

ArgumentError:
  Missing `original_filename` for IO
#gems/ruby-2.4.2/gems/rack-test-0.8.2/lib/rack/test/uploaded_file.rb:67:in `initialize_from_io'
#gems/ruby-2.4.2/gems/rack-test-0.8.2/lib/rack/test/uploaded_file.rb:32:in `initialize'
# ./spec/factories/document.rb:3:in `new'
# ./spec/factories/document.rb:3:in `block (2 levels) in <top (required)>'
#gems/ruby-2.4.2/gems/factory_bot-4.8.2/lib/factory_bot/syntax/default.rb:18:in `instance_eval'
#gems/ruby-2.4.2/gems/factory_bot-4.8.2/lib/factory_bot/syntax/default.rb:18:in `factory'

Again works fine with rack-test 0.7.0

@perlun
Copy link
Contributor

perlun commented Nov 21, 2017

Thanks for the report @aebirim. Could you help me a bit and add some debugging output at gems/ruby-2.4.2/gems/rack-test-0.8.2/lib/rack/test/uploaded_file.rb:32? If we could get the puts content.class.to_s output that would be very helpful!

(Update: this is likely a regression in #210 or #149.)

@perlun perlun added the pending label Nov 21, 2017
@perlun
Copy link
Contributor

perlun commented Nov 23, 2017

@aebirim Still waiting on more info on this so we can fix it.

@aebirim
Copy link
Author

aebirim commented Nov 27, 2017

@perlun, stacktrace for below command:

gem install rack-test -v 0.8.2 --debug --backtrace --verbose

Is that what you'd like ? If not then let me know.

My original error is generated when I run my rspec tests for my models

rspec spec/models

and my test models are created using FactoryBot

@perlun
Copy link
Contributor

perlun commented Nov 27, 2017

@aebirim Thanks. What I mean is more something like this:

  1. Edit the gems/ruby-2.4.2/gems/rack-test-0.8.2/lib/rack/test/uploaded_file.rb file in a text editor of your choice.
  2. At line 32, add a puts content.class.to_s output
  3. Run your specs again.
  4. Paste the output here (or in the gist).

That way, it's much easier to debug since we then know what class the content parameter has. Thanks in advance!

@breckenedge
Copy link

breckenedge commented Dec 4, 2017

@perlun I get File when I add puts content.class.to_s on line 32. It's due to the following test implementation:

**edit: sorry, right after lunch, misread original code :-D **

filepath = File.new(Rails.root.join('test', 'fixtures', 'uploads', 'foobar.dat'))
post :create, params: { foobar_file: filepath }

Obviously not a filepath, but a file. I'm updating our tests to send a path.

@joemsak
Copy link

joemsak commented Dec 7, 2017

I've hit a similar issue trying to run this feature spec

https://gist.github.com/joemsak/771ae438953133230e7093f0ef0eaabf

When click_button is tried a second time, I get a cryptic undefined method size for nil error

I'm willing to discover that the problem is on my end somewhere because I was getting this error the other day because the actual problem was an error in the view or the controller -- but I can't remember how I fixed that instance, and now when I try adding binding.pry to my controller's action, it doesn't get hit

And when I test this scenario by hand in my browser, it works fine.

@arkhamRejek
Copy link

@aebirim did you ever find a way to work around this or fix this ?

@aebirim
Copy link
Author

aebirim commented Dec 12, 2017

yep same result as @breckenedge; @PaulBrunache, @perlun got the following:
interrogration using pry

From: gems/ruby-2.4.2/gems/rack-test-0.8.2/lib/rack/test/uploaded_file.rb @ line 33 Rack::Test::UploadedFile#initialize:

30: def initialize(content, content_type = 'text/plain', binary = false, original_filename: nil)
31:   if content.respond_to?(:read) && (content.is_a?(IO) || content.is_a?(StringIO))
32:   output = content.class.to_s

=> 33: require 'pry' ; binding.pry
34: p output
35: initialize_from_io(content, original_filename)
36: else
37: initialize_from_file_path(content)
38: end
39: @content_type = content_type
40: @tempfile.binmode if binary
41: end
[1] pry(#<Rack::Test::UploadedFile>)> output
=> "File"
[2] pry(#<Rack::Test::UploadedFile>)> content
=> #<File:/Users/abc/app/spec/fixtures/files/test_doc.doc>
[3] pry(#<Rack::Test::UploadedFile>)> content.class
=> File
[4] pry(#<Rack::Test::UploadedFile>)> content.class.to_s
=> "File"

The type of the content is File class

Please advise.

@joemsak
Copy link

joemsak commented Dec 18, 2017

Following up after doing some sleuthing on my end... it seems to happen when submitting a form with file fields. I am not testing that part of the form, so I'm not attaching files. This current investigation is not in relation to the gist I linked in my earlier comment.

The params look like this at Rack::Test::Utils#get_parts

 "technical_checklist[paper_prototype]"=>
  #<Capybara::RackTest::Form::NilUploadedFile:0x00007fd0ac0a1700
   @empty_file=#<File:/var/folders/s7/3_hxsnzs3fg223wk7pk_389c0000gn/T/nil_uploaded_file20171218-30071-1wk5wnd (closed)>>,
 "technical_checklist[paper_prototype_cache]"=>"",
 "technical_checklist[event_flow_chart]"=>
  #<Capybara::RackTest::Form::NilUploadedFile:0x00007fd0ac0a09e0
   @empty_file=#<File:/var/folders/s7/3_hxsnzs3fg223wk7pk_389c0000gn/T/nil_uploaded_file20171218-30071-1rcn59p (closed)>>,

Capybara::RackTest::Form::NilUploadedFile does respond to :original_filename so it goes through to build_file_part, which calls size on it for the Content-Length header on line 136. This is where it ultimately fails (through method_missing attempting to call size on tempfile which is nil)

@joemsak
Copy link

joemsak commented Dec 18, 2017

From Capybara's documentation on NilUploadedFile

Overview
This only needs to inherit from Rack::Test::UploadedFile because Rack::Test checks for the class
specifically when determining whether to construct the request as multipart. That check should be
based solely on the form element's 'enctype' attribute value, which should probably be provided to
Rack::Test in its non-GET request methods.

I don't see it to be true in the current version of the code that Rack::Test is checking for the class, but I am not an expert on the codebase so I could be wrong

@joemsak
Copy link

joemsak commented Dec 18, 2017

Following up once again, I've been able to resolve my issue with this change, which does not break the rack-test test suite joemsak@4adbb1c -- all tests that had the error are now passing, and my entire test suite is passing as well (plenty of my tests do involve attaching files)

@joemsak
Copy link

joemsak commented Dec 19, 2017

Hmmm, I was about to add a test and try to open up the method to a little more polymorphism, when i found this

teamcapybara/capybara@95a297eb

So now I realize the problem is that thoughtbot/[email protected] is not using teamcapybara/[email protected] which supports at least rack-test/[email protected]

@joemsak
Copy link

joemsak commented Jan 2, 2018

If you're using capybara-webkit, thoughtbot recommends using the master branch:

thoughtbot/capybara-webkit#1044 (comment)

I confirm it's working for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants