Reputation: 239
Using Rails 6, I'm redirecting from native ids (/users/id
) to friendly_ids (/users/username
) (following the answer brought here) which handles the redirect as such:
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def redirect_resource_if_not_latest_friendly_id(resource)
if resource.friendly_id != params[:id]
redirect_to resource, status: 301
end
end
end
In my controller, I call the method as such:
# app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:show]
def show
redirect_resource_if_not_latest_friendly_id(set_user)
end
protected
def set_user
@user = User.friendly.find(params[:id])
end
end
It's working fine and I want to include the redirection in my test suite. I found answer and topics about how to do that with Rspec but I'm using Minitest and couldn't figure it out.
I tried a bunch of different ways (with params[:id], etc.) but to keep it simple let's say it's the following fixture, test and result.
Here is the fixture:
# test/fixtures/users.yml
one:
username: username
email: [email protected]
slug: username
Here is the test:
# test/controllers/users_controller_test.rb
class UsersControllerTest < ActionDispatch::IntegrationTest
test "should 301 redirect to the friendly_id" do
@user = users(:one)
get user_path(@user)
assert_redirected_to "/users/#{@user.slug}"
end
end
Here is the result of the test:
FAIL["test_should_301_redirect_to_the_friendly_id", #<Minitest::Reporters::Suite:0x00007fe716c66600 @name="UsersControllerTest">, 0.7785789999979897]
test_should_301_redirect_to_the_friendly_id#UsersControllerTest (0.78s)
Expected response to be a <3XX: redirect>, but was a <200: OK>
test/controllers/users_controller_test.rb:8:in `block in <class:UsersControllerTest>'
What am I doing wrong?
Upvotes: 2
Views: 1096
Reputation: 33420
The problem is you're using the "whole" user record to make the request, so when you do
user_path(@user)
The route extracts the friendly_id from the resource and then your condition is evaluated to false, because the resource.friendly_id is always going to be the same as the id coming from the params.
Try instead:
get user_path(id: @user.id)
That way you can explicitly pass the @user.id through the params.
Upvotes: 1
Reputation: 73
possible the problem resource.friendly_id != params[:id]
as I understood they are the same
Upvotes: 0