Search code examples
ruby-on-railstestingintegration-testing

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. How do you test this?


Solution

  • Created integration test test/integration/multiple_ip_test.rb

    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.