Building Mortimer, day 1
This post is about 6 years due – I cannot remedy that but I can tell you the story up until this moment, and as I move forward, I will let you in on every bump on the road 😇
Clean sheet, volume 4
Did you skip the story? Not sure if you will miss out on any big findings, but should you reconsider – well the link stays 😄
Day 1
Volume 4 is 'the bluebox' and my first task is the mundane one (adding the Devise gem) which I'm not sure if there's any reason for diving too much into [ed. but I ended up somewhere between two bar stools, so there you go] . Here's a post I used for making sure I did not skip the important (moving) parts.
Note to self!
When testing stuff it's important whether you write new_user_session_url
or new_user_session_path
– that your configuration files are correct, otherwise you'll see something along the lines of:
Look for example.com in your config/
files - most likely in environments/test.rb
or application.rb
if you've been tinkering 😉 I've listed it in item 3 below.
Testing the implementation of Devise functionality is not necessary (José Valim ad the rest of Plataformatec and contributors to Devise did a formidable job already) but testing the implementation of Devise in your app certainly is hence I had to find out how to test the as a logged in/out user I want to...
something.
Turns out there are a few things to remember:
- Add encrypted password to your users.yml file
<%= encrypted_password:%=Devise::Encryptor.digest(User,ENV['TEST_PASSWORD']) %>
and the ENV value will have to be add somewhere not pushed to the GitHub repo. Read about environment variables here. I went with.env.test
and inserted a single line (so far) like this:TEST_PASSWORD=w12345678
- Add
include Devise::Test::IntegrationHelpers
totest/test_helper.rb
right at the bottom where they say you can add things like this. - Make sure to add/edit these two lines to
config/environments/test.rb
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
config.action_controller.default_url_options = { host: "localhost", port: 3000 }
- Now edit your
test/controllers/pages_controller_test.rb
to include a test for each of the three most important use cases [ sign_in, sign_out, sign_up ] utilizing the Devise helpers like so:
test "should get home and login path" do
get root_url
assert_response :success
assert_select "a[href=?]", new_user_session_url
end
test "should get home and signout path" do
sign_in users(:one)
get root_url
assert_response :success
assert_select "a[href=?]", destroy_user_session_url
end
test "should get home and sign-up path" do
get root_url
assert_response :success
assert_select "a[href=?]", new_user_registration_url
end
- Watch them fail one by one and then let's go work them green!
The "should get home and signout path" fails because we do not (yet) test for a signed in user! make views/pages/index.html.erb
look like this:
<% if user_signed_in? %>
<h1>Welcome Home, <%= current_user.email %></h1>
<%= link_to 'Sign out', destroy_user_session_url, data: { turbo_method: :delete } %> %>
<% else %>
<h1>Home</h1>
<%= link_to 'Sign in', new_user_session_url %>
<% end %>
If everything else is a-o-k you should at least see one more green test. You may not be 100% in-the-know with line 3 right above here, but Rails 7 going forward utilizes Turbo to the Max so to say. That means this 'link_to' will be a POST with the special _method sauce that Rails is so good at sprinkling all over the entire framework. Read more here.
- Nailing the last test will take yet another line in the
views/pages/index.html.erb
file
...
<%= link_to 'Sign in', new_user_session_url %>
<%= link_to 'Sign up', new_user_registration_url %>
<% end %>
And just like this we managed to implement the 3 more important request paths. Guess it's time for a ☕ and committing with a tag=basic_devise –
- left one test out (which turned out to be quite important) though 😲. Run a system test like this:
require "application_system_test_case"
class DevisesTest < ApplicationSystemTestCase
test "visiting the index" do
visit root_url
click_on "Sign up"
fill_in "Email", with: "mike_hammer@miami.vice"
fill_in "Password", with: "w12345678"
fill_in "Password confirmation", with: "w12345678"
click_on "Sign up"
assert_text "You have signed up successfully"
click_on "Sign out"
assert_text "Sign in"
click_on "Sign in"
fill_in "Email", with: "mike_hammer@miami.vice"
fill_in "Password", with: "w12345678"
click_on "Log in"
assert_text "Sign out"
click_on "Sign out"
assert_text "Sign in"
end
end
This, however, turned out NOT to be that easy! I kept getting a really weird error:
'till this moment I'm not sure why - but I figured a way around (debugging the test showed only the two expected users from my users.yml
) which required a minor rewrite:
require "application_system_test_case"
class DevisesTest < ApplicationSystemTestCase
test "visiting the index" do
unique = DateTime.now.strftime("%Q")
visit root_url
click_on "Sign up"
fill_in "Email", with: "mike_hammer_#{unique}@miami.vice"
...
fill_in "Email", with: "mike_hammer_#{unique}@miami.vice"
...
end
end
- and that was the end of day 1, sort of, but that's a different post 😄