Rspec test not passing because of model name? - ruby-on-rails-3

I'm testing my User model and they can have many aliases:
describe User do
describe "alias associations" do
before { #user.save }
let!(:first_alias) do
FactoryGirl.create(:alias, user: #user, created_at: 1.day.ago)
end
let!(:second_alias) do
FactoryGirl.create(:alias, user: #user, created_at: 1.hour.ago)
end
it "User should have many aliases" do
#user.aliases.should == [first_alias, second_alias]
end
it "should destroy associated aliases" do
aliases = #user.aliases.dup
#user.destroy
aliases.should be_empty
aliases.each do |aliases|
Alias.find_by_id(alias.id).should be_nil
end
end
end
end
My Rspec test is throwing me a loop though. I have a model named Alias and it's giving me this error:
syntax error, unexpected keyword_alias, expecting ')' (SyntaxError)
Alias.find_by_id(alias.id).should be_nil
When I do alias.id it's considered to be a problem.
Why am I getting this error? Is it because of my use of Alias as a model? Changing it to something else gets the test to run.

there are several problems here:
don't use alias, because it's a reserved word
you are passing aliases to the block instead of alias

Related

Guard clause in Rails unless

I am using Rubocop in my rails application and it suggests Use a guard clause instead of wrapping the code inside a conditional expression for this. Plz suggest a clean way to rewrite it.
def exist
#account = Account.find_by(id: params[:id])
unless #account.present?
render json: { error: 'Account is not available' }, status: :not_found
end
end
RuboCop is suggesting a change such as this:
def exist
#account = Account.find_by(id: params[:id])
render json: { error: 'Account is not available' }, status: :not_found unless #account.present?
end
But whether this is more 'clean' is subjective.

How to return the correct fields in Rails API?

I have these two tables - User, Accounts.
User contains an authentication key,
Accounts contains the list of accounts.
I am trying to get the list of accounts for the user if the authentication key is correct.
So in the controller I have -
def show
#user = User.where(authentication_token: params[:authentication_token])
render json: #user.as_json(
only: [:email, :id, :authentication_token]
),
status: :created
end
This would just return the user details. How can i edit it so it first checks if the user exists with that Authentication_token, and then uses the UserID, in the accounts table to get the list of accounts ?
Your question is a little unclear: What is the desired behaviour if the authentication_token is not correct? Raise an exception? Redirect somewhere? Display a flash message? ...
You could, for example, do something like this:
def show
if authenticated_user
render json: authenticated_user.accounts.as_json(
only: [:id, :foo, :bar]
),
status: :ok
else
render json: { errors: { authentication_token: 'Invalid' } },
status: :unauthorized
end
end
private
def authenticated_user
#authenticated_user ||= User.find_by(
authentication_token: params[:authentication_token]
)
end

Destroy method failing in controller test

I'm experiencing a bizarre issue testing a destroy method. I'm using FactoryGirl and Rspec.
Here's a look at the method in question. As you can see, it doesn't actually destroy the dealer, just set it and it's dependent object's active attributes to false:
dealers_controller.rb
def destroy
#dealer = Dealer.find(params[:id])
#dealer.active = false
#dealer.save!
#dealer.leads.each { |lead|
lead.active = false
lead.save!
}
#dealer.users.each { |user|
user.active = false
user.save!
}
redirect_to dealers_path
end
When I run this method in the application it does exactly what it should do. Now, on to the test.
dealers_controller_spec.rb
describe "#destroy" do
context "when deleting a valid record" do
let(:dealer) { FactoryGirl.create(:dealer_with_stuff) }
before do
#user = FactoryGirl.build(:admin_user)
login_user
delete :destroy, :id => dealer.id
end
it { should assign_to(:dealer).with(dealer) }
it { should redirect_to(dealers_path) }
it { should set_the_flash }
it "is no longer active" do
dealer.active.should be_false
end
it "has no active users" do
dealer.users.each do |user|
user.active.should be_false
end
end
it "has no active leads" do
dealer.leads.each do |lead|
lead.active.should be_false
end
end
end
end
The first 3 tests pass, but the last 3 all fail (weirdly, the user.active.should be_false test only fails if I put a sleep(10) after delete :destroy up above, but let's not get into that issue now). So when I check the test log, it goes through the entire destroy process, but then does a ROLLBACK, so for some reason it doesn't save any of the records; but it doesn't give me any more information than that.
Does anyone have any thoughts on this? I've tried everything I can possibly think of.
What if you reload the dealer? The dealer in your tests is different from the #dealer object in the controller (ActiveRecord doesn't do identity maps).
before do
#user = FactoryGirl.build(:admin_user)
login_user
delete :destroy, :id => dealer.id
dealer.reload # << add this
end

validates_acceptance_of still saves the record

I am using ruby 1.9.2-p180, rails 3.0.7. I have used validates_acceptance_of since the user has to agree to our terms and conditions. We don't have a column for this, but I understand that "If the database column does not exist, the terms_of_service attribute is entirely virtual. " from http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M000082
Anyway, I double checked this by smoke testing the app manually and I see from the logs that the record is still inserted into the db, which is weird because upon submitting the form, I am redirected back to the form with the error: "Must agree to terms and conditions"(which made me think it worked before)
Am I doing something wrong here?
_form.haml:
%label.checkbox-label{:for => "operator_terms_and_conditions"}
= f.check_box :terms_and_conditions
I agree to
= link_to "Terms and Conditions", operator_terms_path, :target => "_blank"
operators_controller:
def create
user_params = params[:operator][:user]
user_params.merge!(:login => user_params[:email])
#password = params[:operator][:user][:password]
Operator.transaction do # don't save User if operator is invalid
#operator = Operator.create(params[:operator])
end
respond_to do |format|
unless #operator.new_record?
UserMailer.operator_confirmation_email(#operator, #password).deliver
UserMailer.operator_registration_admin_notification_email(#operator).deliver
UserSession.create(#operator.user)
format.html {redirect_to new_operator_aircraft_path}
else
format.html { render :action => "new" }
end
end
end
and in the model:
validates_acceptance_of :terms_and_conditions
Found the answer. The problem was not with validates_acceptance_of but rather with how I was saving the data. When an operator was created, a user was also created that was tied to it and it was this user that was being inserted into the db.
This happens because although the operator was being rolled back(because it wasn't valid) the user was still created(because it was not in a transaction).
I solved this by using nested_transactions:
operator model:
...
User.transaction(:requires_new => true) do
create_user
raise ActiveRecord::Rollback unless self.valid?
end
...

Receiving "unknown method" errors when running RSpec tests against an ActiveRecord model

I'm having a bit of trouble with some RSpec tests on some of my ActiveRecord validations. The test suite looks like this:
describe Event do
context "An Event" do
before do
valid_event_hash = {
:name => 'Blah Blah',
:desc => 'Yadda Yadda Yadda',
:category => 'some category',
:has_partner => false,
:event_abbr => 'BB'
}
#event = Event.new(valid_event_hash)
end
it "should have a name" do
#event.name = ''
#event.should_not be_valid
end
it "should have a description" do
#event.desc = ''
#event.should_not be_valid
end
it "should have an abbreviation no shorter than 2 letters and no longer than 3 letters" do
#event.event_abbr = ''
#event.should_not be_valid
#event.event_abbr = 'BlaBla'
#event.should_not be_valid
#event.event_abbr = 'B'
#event.should_not be_valid
end
after do
#event.destroy
end
end
end
The model is set up so that it should pass all of these validations appropriately. The schema indicates that all of the fields I fill in are present and accounted for. Yet, when I run autotest, the tests fail with the following error:
Failure/Error: #event = Event.new(valid_event_hash)
unknown attribute: event_abbr
I can create the very same #event instance in the console with those values, and it works perfectly. My gut reaction is that, for some reason, the model that the test suite is using doesn't know about the :event_abbr field, but I can't think why that might be. I'm sure I'm missing something, but I'm not sure what it is. Any help would be greatly appreciated.
Did you run your migrations on your test database? E.G.
RAILS_ENV=test rake db:migrate
else, try
rails console test
and try it there.