How to test login from multiple IP addresses in Rails
At the request of a customer, I had to implement sending a notification email every time the application detects two active sessions for the same user from different IP addresses. I could not find a good example on how to test this functionality, so I decided to write a post showing my solution.
I created integration test test/integration/multiple_ip_test.rb
. I my opinion, Rails integration tests are underutilized, this makes difficult to find sample code that goes beyond the basic cases.
require 'test_helper' @@default_ip = "127.0.0.1" class ActionController::Request def remote_ip @@default_ip end end class MultipleIpTest < ActionDispatch::IntegrationTest fixtures :all test "send email notification if login from different ip address" do post_via_redirect login_path, :user => {:username => "john", :password => "test"} assert_equal "/users/john", path reset! @@default_ip = "200.1.1.1" post_via_redirect login_path, :user => {:username => "john", :password => "test"} assert_equal "/users/john", path assert_equal 1, ActionMailer::Base.deliveries.size end end
Integration tests look a lot like functional tests, but there are some differences. You cannot use @request
to change the origin IP address. This is why I had to open the ActionController::Request
class and redefine the remote_ip
method.
Because the response to post_via_redirect
is always 200, instead of using assert_response :redirect
I use the URL to verify the user has logged in successfully.
The call to reset!
is necessary to start a new session.
For an introduction on integration tests, check the Rails Guides on testing, unfortunately they do not mention the reset!
method.