-
-
Notifications
You must be signed in to change notification settings - Fork 40
Testing
Janko Marohnić edited this page Dec 25, 2023
·
7 revisions
System (browser) tests for Rodauth actions could look something like this:
# test/system/authentication_test.rb
require "test_helper"
class AuthenticationTest < ActionDispatch::SystemTestCase
include ActiveJob::TestHelper
driven_by :rack_test
test "creating and verifying an account" do
create_account
assert_match "An email has been sent to you with a link to verify your account", page.text
verify_account
assert_match "Your account has been verified", page.text
end
test "logging in and logging out" do
create_account(verify: true)
logout
assert_match "You have been logged out", page.text
login
assert_match "You have been logged in", page.text
end
private
def create_account(email: "[email protected]", password: "secret", verify: false)
visit "/create-account"
fill_in "Login", with: email
fill_in "Password", with: password
fill_in "Confirm Password", with: password
click_on "Create Account"
verify_account if verify
end
def verify_account
perform_enqueued_jobs # run enqueued email deliveries
email = ActionMailer::Base.deliveries.last
verify_account_link = email.body.to_s[/\S+verify-account\S+/]
visit verify_account_link
click_on "Verify Account"
end
def login(email: "[email protected]", password: "secret")
visit "/login"
fill_in "Login", with: email
fill_in "Password", with: password
click_on "Login"
end
def logout
visit "/logout"
click_on "Logout"
end
end
While request tests in JSON API mode with JWT tokens could look something like this:
# test/integration/authentication_test.rb
require "test_helper"
class AuthenticationTest < ActionDispatch::IntegrationTest
test "creating and verifying an account" do
create_account
assert_response :success
assert_match "An email has been sent to you with a link to verify your account", JSON.parse(body)["success"]
verify_account
assert_response :success
assert_match "Your account has been verified", JSON.parse(body)["success"]
end
test "logging in and logging out" do
create_account(verify: true)
logout
assert_response :success
assert_match "You have been logged out", JSON.parse(body)["success"]
login
assert_response :success
assert_match "You have been logged in", JSON.parse(body)["success"]
end
private
def create_account(email: "[email protected]", password: "secret", verify: false)
post "/create-account", as: :json, params: { email: email, password: password, "password-confirm": password }
verify_account if verify
end
def verify_account
perform_enqueued_jobs # run enqueued email deliveries
email = ActionMailer::Base.deliveries.last
verify_account_key = email.body.to_s[/verify-account\?key=(\S+)/, 1]
post "/verify-account", as: :json, params: { key: verify_account_key }
end
def login(email: "[email protected]", password: "secret")
post "/login", as: :json, params: { email: email, password: password }
end
def logout
post "/logout", as: :json, headers: { "Authorization" => headers["Authorization"] }
end
end
Note: Rails now discourages these tests in favor of ActionDispatch::Integration
tests.
Since these tests don't load the middleware stack, Rodauth routes won't be available here. To authenticate the session, you can call Rodauth methods directly:
# test/controllers/articles_controller_test.rb
class ArticlesControllerTest < ActionController::TestCase
test "required authentication" do
get :index
assert_response 302
assert_redirected_to "/login"
assert_equal "Please login to continue", flash[:alert]
account = Account.create!(email: "[email protected]", password: "secret123", status: "verified")
login(account)
get :index
assert_response 200
logout
get :index
assert_response 302
assert_equal "Please login to continue", flash[:alert]
end
private
# Call `rodauth(:admin)` if you want to use a secondary :admin configuration
def login(account)
rodauth.account_from_login(account.email)
rodauth.login_session("password")
end
def logout
rodauth.logout
end
end
If you're using RSpec, you'll need to first include the controller test helpers:
RSpec.configure do |config|
config.include Rodauth::Rails::Test::Controller, type: :controller
end
If you're delivering emails in the background, make sure to set Active Job
queue adapter to :test
or :inline
:
# config/environments/test.rb
Rails.application.configure do |config|
# ...
config.active_job.queue_adapter = :test # or :inline
# ...
end