Forum: RSpec Testing file upload (Sinatra, RSpec, Rack-Test)

Posted by P. A. (polunochnik)
on 2010-03-13 19:40
Hi.

I have a simple application and I want to add a file upload
functionality. How can I write a spec?

Here's my try.

# directory structure
app:
 - controller.rb
 - controller.spec.rb
 - files: []
 - fixtures: [test_file.png]

# controller.spec.rb
require 'rack/test'
require 'controller'

module MyHelpers
 def app
  Sinatra::Application
 end
end

Spec::Runner.configure do |conf|
 conf.include Rack::Test::Methods
 conf.include MyHelpers
end

describe 'Application' do
 it 'should accept uploaded files and save them into the `files`
directory'
  post '/', 'file' =>
Rack::Test::UploadedFile.new('fixtures/test_file.png', 'image/png')
  Dir['files/*'].should include('files/test_file.png')
 end
end

# controller.rb
require 'sinatra'
require 'fileutils'

post '/' do
 tempfile = params['file'][:tempfile]
 FileUtils.copy_file(tempfile.path, 'files')
end

But when I ran...

$ spec -f specdoc controller.rb

...I get the following output.

Application
- should accept uploaded files and save them into the `files` directory
(FAILED - 1)

1)
'Application should accept uploaded files and save them into the `files`
directory' FAILED
expected [] to include "files/test_file.png"
<path_to_app>/controller.spec.rb:<line_number>:in `block (2 levels) in
<top (required)>'

Finished in 0.132799038 seconds

1 example, 1 failure

What I do wrong?

Thanks.

Debian GNU/Linux 5.0.4;
Ruby 1.9.2;
Sinatra 0.9.6;
RSpec 1.3.0;
Rack-Test 0.5.3.
Posted by P. A. (polunochnik)
on 2010-03-13 20:21
P. A. wrote:
> Hi.
> 
> I have a simple application and I want to add a file upload
> functionality. How can I write a spec?
> 
> Here's my try.
> 
> # directory structure
> app:
>  - controller.rb
>  - controller.spec.rb
>  - files: []
>  - fixtures: [test_file.png]
> 
> # controller.spec.rb
> require 'rack/test'
> require 'controller'
> 
> module MyHelpers
>  def app
>   Sinatra::Application
>  end
> end
> 
> Spec::Runner.configure do |conf|
>  conf.include Rack::Test::Methods
>  conf.include MyHelpers
> end
> 
> describe 'Application' do
>  it 'should accept uploaded files and save them into the `files`
> directory'
>   post '/', 'file' =>
> Rack::Test::UploadedFile.new('fixtures/test_file.png', 'image/png')
>   Dir['files/*'].should include('files/test_file.png')
>  end
> end
> 
> # controller.rb
> require 'sinatra'
> require 'fileutils'
> 
> post '/' do
>  tempfile = params['file'][:tempfile]
>  FileUtils.copy_file(tempfile.path, 'files')
> end
> 
> But when I ran...
> 
> $ spec -f specdoc controller.rb
> 
> ...I get the following output.
> 
> Application
> - should accept uploaded files and save them into the `files` directory
> (FAILED - 1)
> 
> 1)
> 'Application should accept uploaded files and save them into the `files`
> directory' FAILED
> expected [] to include "files/test_file.png"
> <path_to_app>/controller.spec.rb:<line_number>:in `block (2 levels) in
> <top (required)>'
> 
> Finished in 0.132799038 seconds
> 
> 1 example, 1 failure
> 
> What I do wrong?
> 
> Thanks.
> 
> Debian GNU/Linux 5.0.4;
> Ruby 1.9.2;
> Sinatra 0.9.6;
> RSpec 1.3.0;
> Rack-Test 0.5.3.

I found out the source of the problem by myself. It was in the 
FileUtils.copy_file method. As it turned out this method doesn't accept 
a directory name as the second argument. It needs both the first 
argument and the second argument to be a file names. So, the updated 
code looks like the following.

# controller.rb
post '/' do
 tempfile = params['file'][:tempfile]
 FileUtils.copy_file(tempfile.path, 
"files/#{params['file'][:filename]}") # the problem was here
end

All works now (and that's enough for man to be happy).

Thank you for your attention.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.