I am currently studying Rspec in the Introduction to Rails Testing with Everyday Rails Rspec
"We are testing using requestspec to ""send Post to make sure DB has one more target data"", but the test has failed due to the following error:
error
expected Project:: ActiveRecord_Associations_CollectionProxy #count to have changed by 1, but was changed by 0
I debugged some of them and put out the error screen, and I was stuck with Rails' CSRF countermeasures such as Can't verify CSRF token authenticity
, so this is probably the reason.
We use Device for user login authentication.
We use Rsepc's FactoryBot for user generation and target data generation (Project).
Also, the version of Rails I am currently using is 7.0, so I am not sure how to pass the CSRF countermeasure, so I would appreciate it if you could let me know if anyone knows.
spec/requests/projects_api_spec.rb
require 'rails_helper'
RSpec.describe "ProjectsApis", type: :request do
# This test is successful.
it "create one project" do
user=FactoryBot.create(:user)
FactoryBot.create(:project, name: "Sample Project")
FactoryBot.create(:project, name: "Second Sample Project", owner:user)
get api_projects_path, params: {
user_email: user.email,
user_token —user.authentication_token
}
expect(response).to have_http_status(:success)
json=JSON.parse(response.body)
expect(json.length).to eq1
project_id=json[0]["id"]
get api_projects_path(project_id), params: {
user_email: user.email,
user_token —user.authentication_token
}
expect(response).to have_http_status(:success)
json=JSON.parse(response.body)
expect(json[0]["name"]).to eq "Second Sample Project"
end
# This test has failed.
it "Be able to create a project" do
user=FactoryBot.create(:user)
project_attributes=FactoryBot.attributes_for(:project)
expect{
post api_projects_path, params: {
user_email: user.email,
user_token —user.authentication_token,
project —Project_attributes
}
}.to change(user.projects,:count).by(1)
expect(response).to have_http_status(:success)
end
end
app/controllers/application_controller.rb
class ApplicationController<ActionController::Base
before_action —Authenticate_user!
protected
default_project
@project=Project.find(params[:project_id])
end
def project_owner ?
[email protected]==current_user
redirect_to root_path, alert: "You don't have access to that project."
end
end
end
spec/factories/projects.rb
FactoryBot.definedo
factory —Project do
sequence(:name) {|n|"Project#{n}"}
description {"A test project"}
due_on {1.week.from_now}
association:owner
# a project with a note
trace —with_notes do
after(:create) { | project | create_list(:note, 5, project:project)}
end
# a project due yesterday
trace —due_yesterday do
due_on {1.day.ago}
end
# project due today
trace —due_today do
due_on {Date.current.in_time_zone}
end
# a project due tomorrow
trace —due_tomorrow do
due_on {1.day.from_now}
end
# be disabled
trace —Invalid do
name {nil}
end
end
end
FactoryBot.definedo
factory:user, aliases:[:owner] do
first_name {"Aaron"}
last_name {"Sumner"}
sequence(:email) { | n | "tester#{n}@e-xample.com"}
password {"dottle-nouveau-pavillion-tights-furze"}
end
end
Rails 7.0 defaults to config.action_controller.allow_forgery_protection
with false
skipped CSRF token validation: in the test environmenthttps://github.com/rails/rails/blob/1a22ebc/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt#L33-L34
If you don't even need to verify the CSRF token during the test, check this setting.
If you want to verify the CSRF token during the test, it would be better to explicitly give the token in the request spec.You should use ActionController::RequestForgeryProtection #form_authenticity_token
to generate your own token and pass it as a parameter named authenticity_token
.
By the way, the failure of the test may not be due to the CSRF token.The error message that the test failed is that the count
has not changed as intended, not that the POST request failed.If the POST request has failed, the error should appear before detecting the change.
So, maybe post api_projects_path
is really not creating a new record?Please review the implementation of the controller that handles this request.
© 2024 OneMinuteCode. All rights reserved.