validating presence of attribute fails - rspec2

In my class Foo, I have:
belongs_to :assessment_type
validate :assessment_type, presence: true
My RSpec test has:
it { is_expected.to validate_presence_of(:assessment_type) }
The test fails with this error:
1) Foo should require assessment_type to be set
Failure/Error: it { is_expected.to validate_presence_of(:assessment_type) }
Expected errors to include "can't be blank" when assessment_type is set to nil, got errors: ["can't be blank (attribute: \"name\", value: nil)", "can't be blank (attribute: \"description\", value: nil)", "can't be blank (attribute: \"logo\", value: nil)", "can't be blank (attribute: \"url_code\", value: nil)", "can't be blank (attribute: \"starts_at\", value: nil)", "can't be blank (attribute: \"contract\", value: nil)", "can't be blank (attribute: \"organization\", value: nil)"]
All of the attributes listed in the errors string (name, description, ...) have the same validate statement as assessment_type.
Why is this failing?

I found the problem. This line:
validate :assessment_type, presence: true
should be
validates :assessment_type, presence: true

Related

How do I validate Array and string in same params through rails params gem validation

I have use Rails params gem for rails params validation
param! :answers, Array, blank: false, required: true do |x|
x.param! :value, String, blank: false, reqiured: true, message: 'Value Can\'t Blank'
end
value is both
params = "some random string" or params = ["some random string", "some random string", "some random string"]
In that params, value key was accept both string and array, I don't how to handle it
I did not found anything like or or a support of multiple types.
Maybe you can use transform to cast your string to an array (code is not tested):
x.param! :value, Array, blank: false, reqiured: true, transform: lambda { |val| [val].flatten.reject(&:blank?) }, message: 'Value Can\'t Blank'

Ruby on Rails: RSpec not working with validation

I have fairly simple model but I'm getting RSpec failures that I cannot find the solution to.
Model -
store_accessor :properties, :fields
store_accessor :priorities
belongs_to :user
belongs_to :external_service
validates :user, :external_service, presence: true
validate :service_enabled?
validates_presence_of :properties, message => "This field is non editable"
Rspec -
require 'rails_helper'
module Application
describe Integration, type: :model do
it { should validate_presence_of(:user) }
it { should validate_presence_of(:external_service) }
it { should validate_presence_of(:properties) }
context 'external service' do
let(:service) { Application::ExternalService.new }
before do
allow(subject).to receive(:external_service).and_return(service)
end
end
end
end
This is the failure that I am getting:
Failure -
Application::Integration should require properties to be set
Failure/Error: it { should validate_presence_of(:properties) }
Expected errors to include "can't be blank" when properties is set to nil,
got errors:
* "can't be blank" (attribute: user, value: nil)
* "can't be blank" (attribute: external_service, value: nil)
* "The service must be enabled to add an integration." (attribute: external_service, value: nil)
* "This field is non editable" (attribute: properties, value: nil)
By default validates_presence_of consider error message as can't be blank. but, as you are setting custom validation message then, you have to verify the same using with_message in spec
it { should validate_presence_of(:properties).with_message('This field is non editable') }
Example for validate_presence_of with with_message

How can I accept the nil value of a param while there is also a format defined?

This is the validation:
validates :phonenumber, allow_nil: true, format: { with: /\A\d{10}\z/, message: "not valid" }
When I do not put any value into phonenumber, it give me the error "phonenumber not valid". How can I solve this problem?
I guess you need to use allow_blank option:
validates :phonenumber,
format: { with: /\A\d{10}\z/, message: "not valid" },
allow_blank: true

RSpec with website format validation fails

I'm using rails4, factory_ girl, rspec and shoulda matchers. If I run rspec with the code below I get this error:
Product should validate that :website cannot be empty/falsy, producing a custom validation error on failure
Failure/Error: self.website = "http://#{self.website}" unless self.website[/^https?/]
NoMethodError:
undefined method `[]' for nil:NilClass
If I delete unless self.website[/^https?/] from the format_website method I get this error:
Product did not properly validate that :website cannot be empty/falsy,
producing a custom validation error on failure.
After setting :website to ‹nil› -- which was read back as ‹"http://"›
-- the matcher expected the Product to be invalid and to produce a
validation error matching ‹/can't be blank/› on :website. The record
was indeed invalid, but it produced these validation errors instead:
* user: ["can't be blank"]
* name: ["can't be blank"]
* company: ["can't be blank"]
What should I do to make this work?
product model
belongs_to :user
validates :name, presence: { message: "can't be blank" }, length: { maximum: 140, message: "can't be longer than 140 characters" }, uniqueness: { message: "already exists" }
validates :company, presence: { message: "can't be blank" }, length: { maximum: 140, message: "can't be longer than 140 characters" }
validates :website, presence: { message: "can't be blank" }, length: { maximum: 140, message: "can't be longer than 140 characters" }
before_validation :format_website
validate :website_validator
def format_website
self.website = "http://#{self.website}" unless self.website[/^https?/]
end
def website_validator
self.errors.add :website, "format is invalid!" unless website_valid?
end
def website_valid?
!!website.match(/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-=\?]*)*\/?$/)
end
factory
FactoryGirl.define do
factory :product do
name { Faker::Commerce.product_name }
company { Faker::Company.name }
website { 'https://example.com' }
user
end
end
it { is_expected.to callback(:format_website).before(:validation) } #this one is not important, if I take out it still gives the same error
it { is_expected.to validate_presence_of(:name).with_message(/can't be blank/) }
it { is_expected.to validate_presence_of(:company).with_message(/can't be blank/) }
it { is_expected.to validate_presence_of(:website).with_message(/can't be blank/) }
it { is_expected.to belong_to(:user) }
You should ensure that website is not nil.
def format_website
return if website.blank?
self.website = "http://#{self.website}" unless self.website[/^https?/]
end
In that case, if self.website == nil, you'll try to call the method [] on a nil object, hence the first error.
For the second case, the answer is in the return you have from rspec:
After setting :website to ‹nil› -- which was read back as ‹"http://"›
Your method format_website returns "http://", which is because website is nil.

Rspec validates length

I'm learning rspec, I try to valitade length of my model, but I have this errors and I don't know what is going wrong?
#factories/user
FactoryGirl.define do
factory :user do
first_name {"Name"}
last_name {"Surename"}
phone_number {"1245767"}
email {"email#email.net"}
password {"password"}
end
end
user_spec: it { should validate_length_of(:phone_number).is_at_least(7)}
user model: validates_length_of :phone_number, minimum: 7
error:
User validations should ensure phone_number has a length of at least 7
Failure/Error: it { should validate_length_of(:phone_number).is_at_least(7)}
Did not expect errors to include "is too short (minimum is 7 characters)" when phone_number is set to "xxxxxxx",
got errors:
* "can't be blank" (attribute: email, value: "")
* "can't be blank" (attribute: password, value: nil)
* "is too short (minimum is 7 characters)" (attribute: phone_number, value: 0)
* "can't be blank" (attribute: first_name, value: nil)
* "can't be blank" (attribute: last_name, value: nil)
thank you
#edit
require 'rails_helper'
describe User do
describe 'validations' do
it { should validate_presence_of :first_name }
it { should validate_presence_of :last_name }
it { should validate_presence_of :phone_number }
it { should validate_length_of(:phone_number).is_at_least(7)}
end
end
When using an implicit subject, RSpec instantiates the class for you, e.g.:
describe User
it { should_blah_blah }
end
At this point the subject (meaning the thing referred to by it) is an instance of User created by calling User.new. This is convenient for some unit tests, but in your case you want to initialize the user with a factory. Use the explicit subject, e.g.:
describe User
subject { build(:user) }
it { should_blah_blah }
end
Now the subject is a User instance initialized from the factory definition.
More info in the RSpec docs

Resources