Question

I see plenty that lead to custom authorization strategies for devise and warden, but what I'm sepcifically after is testing these solutions with rspec. Similar to this question: Filtering users who are able to sign in with Devise

What can I do to test this sort of implementation. Rails 3.1.1, Devise (most current), etc.

Was it helpful?

Solution

For those that may do this in the future, here is my solution:

This is the class that sets a new strategy for authentication through Devise (and it could also be used with Warden with a few small changes).

require 'devise/strategies/authenticatable'

module Devise
  module Strategies
    class AndroidAuthenticatable < Authenticatable
      def valid? 
        # return true/false
                return valid_params? && valid_headers?
      end 

      def authenticate! 
        failure_message = "Authentication failed for device/user"

        klass = mapping.to # if we're going to come here, we can mock this
        begin
          # code to determine whether or not to authenticate this request
          # if yes, success!(instance of klass)
          # if no, fail!(messsage)
        rescue
          fail!(failure_message) # always fail if not success
        end
      end 

      protected
      def valid_params?
        # params that show whether request should be here
      end

      def valid_headers?
        # headers that determine if request should be here
      end
    end
  end
end

The previous class is in my lib/.../strategies directory. I also have lib configured for auto-loading through the rails configuration.

From the rspec side, after I created the above class I write out a few stubs/mocks. Here is a basic rspec file to get you started.

# I do this in before block or right before test executes
@request = mock(:request)
@strategy = Devise::Strategies::AndroidAuthenticatable.new(nil)
@request.should_receive(:headers).and_return({#hash of the headers you are testing})
@strategy.should_receive(:params).at_least(:once).and_return({#hash of the params})
@strategy.should_receive(:request).and_return(@request)

# Break these up as needed to test failing and successful 
# strategies for your application
lambda {
   @strategy.should be_valid
   @strategy.authenticate!.should eql :success 
}.should_not raise_error

This isn't all inclusive, but I feel it should get us a good head start when adding strategies with Warden or Devise. I actually had to implement what I thought would work and then right tests to prove it after the fact. Now we can do it the other way around perhaps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top