I am having trouble running a rspec test on the following model:
class Sound < ActiveRecord::Base
belongs_to :user
# for paperclip
has_attached_file :sound_file
# do not create a sound unless a sound file
# is present
validates_attachment_presence :sound_file
end
Specifically, I am trying to test the create route. From my controller:
def create
@sound = Sound.create( sound_params )
redirect_to sound_url(@sound)
end
private
def sound_params
params.require(:sound).permit(
:sound_file,
:sound_name,
:description,
:location)
end
Here is what I first wrote in my sounds_controller_spec.rb file:
describe "POST #create" do
it 'creates a new sound' do
tester_sound = FactoryGirl.create(:sound,
:sound_name => 'test',
:sound_file => File.open('/Users/christopherspears/wdi/83746__braffe2__pen-writing.wav'))
post :create, sound: tester_sound
expect(Sound.last.sound_name).to eq(tester_sound[:sound_name])
end
end
I got this error message:
1) SoundsController POST #create creates a new sound
Failure/Error: post :create, sound: tester_sound
NoMethodError:
undefined method `permit' for "54":String
# ./app/controllers/sounds_controller.rb:53:in `sound_params'
# ./app/controllers/sounds_controller.rb:16:in `create'
# ./spec/controllers/sounds_controller_spec.rb:39:in `block (3 levels) in <top (required)>'
Strangely enough, I think the '54' is somehow connected to this file path: /Users/christopherspears/wdi/HearHere/public/system/sounds/sound_files/000/000/054/original/83746_braffe2_pen-writing.wav
A colleague suggested that I just pass a hash with Sound's parameters to the test:
describe "POST #create" do
it 'creates a new sound' do
tester_hash = {:sound_name => 'test',
:sound_file => File.open('/Users/christopherspears/wdi/83746__braffe2__pen-writing.wav')}
post :create, sound: tester_hash
expect(Sound.last.sound_name).to eq(tester_hash[:sound_name])
end
end
Unfortunately, that brought up another error:
Failures:
1) SoundsController POST #create creates a new sound
Failure/Error: post :create, sound: tester_hash
Paperclip::AdapterRegistry::NoHandlerError:
No handler found for "#<File:0x007ff603de0868>"
# ./app/controllers/sounds_controller.rb:16:in `create'
# ./spec/controllers/sounds_controller_spec.rb:48:in `block (3 levels) in <top (required)>'
I don't think I'm doing anything unusual with the routes:
get 'sounds/:id/download' => 'sounds#download', :as => :download
resources :sounds
Any advice? Seems like testing the controller of a model with validates_attachment_presence is going to be a bit of a challenge.
UPDATE
I'm trying a different method now.
let(:valid_attributes) { { "sound_name" => "test", "sound_file" => File.new } }
let(:valid_session) { {} }
describe "POST #create" do
it 'creates a new sound' do
sound = FactoryGirl.create(:sound => valid_attributes)
expect { sound.sound_name }.to eq("test")
end
end
Well, at least I get a different error message:
Failures:
1) SoundsController POST #create creates a new sound
Failure/Error: let(:valid_attributes) { { "sound_name" => "test", "sound_file" => File.new } }
ArgumentError:
wrong number of arguments (0 for 1..3)
# ./spec/controllers/sounds_controller_spec.rb:4:in `initialize'
# ./spec/controllers/sounds_controller_spec.rb:4:in `new'
# ./spec/controllers/sounds_controller_spec.rb:4:in `block (2 levels) in <top (required)>'
# ./spec/controllers/sounds_controller_spec.rb:38:in `block (3 levels) in <top (required)>'
Not sure what is causing this...