Clearance with Test::Unit - ruby-on-rails

I am using Clearance for authentication with my rails app which works. But now all my unit tests fail because they redirect to the sign in page, which makes sense. Clearance seems to have helper functions for fixing that but I can only find them for Shoulda. Are there equivalent helpers for Test::Unit?

I thought there'd be more 'magic' to how the shoulda macros work but it's actually really simple. To add the sign_in behavior just add this to the test_helper.rb
def sign_in_as(user)
#controller.current_user = user
return user
end

Related

rails don't calls the engine's controller

I am trying to define some helper methods to be used in the app's controller, but it seems that rails don't even call the controller. just for the test I have the following controller in my app/controllers/my_engine/application_controller.rb and as the documents say rails should find it first and an error should raise because THIS_SHOULD_PRODUCE_ERROR is unknown, but the rspec happily executing without any errors!
class ApplicationController < ActionController::Base
THIS_SHOULD_PRODUCE_ERROR
end
I even tried to mimic the devise's way but the results are the same!
The guide section on the app directory suggests that the application_controller in an engine "will provide any common functionality for the controllers of the engine".
So I wouldn't expect that any additions to that controller will be available to all controllers in an application.
That also means that your application_controller is, I suspect, not getting called when you're running your test. Which would explain why you're not seeing an error.
In terms of how devise does it I think you need to be looking at how define_helpers works. The code you've linked to in your question is the application controller in the test app for the devise gem.
I noticed that I have got things wrong, and the application_controller in the engine does not get applied to application_controller in the app! Also, I couldn't figure out how the devise did it, but I have come up with the simple workaround for this:
require_relative 'controllers/helpers'
module Acu
module Injectors
class << self
ActiveSupport::Notifications.subscribe "start_processing.action_controller" do |**args|
eval((Acu::Configs.get :base_controller).to_s).class_eval do
include Acu::Controllers::Helpers
end
end
end
end
end
This will inject controller helpers to the user's base controller (which I get from the user, default: :ApplicationController) at the end of the class, which is perfect for me (but don't know how to add it to begging of the class if anyone needs it)

Stubbing Warden on Controller Tests

I'm having an issue with testing my controllers and using Warden.
All examples point at stubbing request.env['warden']. This causes issues in my controllers when I call env['warden'], which then returns nil.
For a crude example, using this:
request.env['warden'] = double(Warden, :authenticate => nil,
:authenticate! => nil,
:authenticated? => false)
And a simple before filter like this:
before_filter do
redirect_to new_user_session_url unless env['warden'].authenticated?
end
I get a nil.
I just managed to get it working using controller.env['warden'] = ... and it works.
This makes sense, since it's sitting right at the controller level, so I guess my question is what wouldn't it work in the I've seen all examples.
I have this in my spec_helper:
config.include Warden::Test::Helpers
Any help would be great!
I wrote controller test helpers for Warden.
http://kentaroimai.com/articles/1-controller-test-helpers-for-warden
Despite many examples telling you to implement Warden through env['warden'] in your Rails app. It seems the correct way to access it through request.env['warden'].
It found this out by raising env in my controllers during tests, and this always came out nil.
It seems in Warden, https://github.com/hassox/warden/blob/master/lib/warden/proxy.rb#L13
There is an accessor for the rack environment, which won't exist in test mode due to the absence of Rack in controller tests. Please someone check this.
So when stubbing request.env in RSpec, your implementation needs to point at request.env.
It seems a necessary evil in my mind. But if there is anyone with a good explanation or work around, I'd love to continue this discussion.

Ruby on Rails - Reload Class Cache on Demand

Does Ruby on Rails 3 (3.0.7) offer a mechanism to reload the class cache on demand? I am running some tests where I overwrite some methods in ApplicationController and in some of my models to stub out authentication. For example, I call a method (I'm using Cucumber for testing) in some of my tags (Before('#tag')) that does this:
ApplicationController.send(:define_method, :current_user) do
#current_user ||= User.where(:id => cookies[:user_id]).first
end
...where the actual current_user method in ApplicationController has a different behavior.
This works great until I need to run some tests in which I do not want to stub out those methods. With config.cache_classes = true set in my test environment, ApplicationController is not reinitialized without my monkey patch, making the tests I don't want to stub out fail. With config.cache_classes = false, my monkey patch is forgotten on the next request, causing all of the tests that I need to stub to fail.
Ideally, I would like to be able to erase the class cache in an After('#tag') method, if this is possible. How can I accomplish that? Or is there a better way of stubbing out certain methods in certain scenarios that I am overlooking?
You could take inspiration from this great SO answer, and make good use of ActionDispatch::Callbacks.
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader.prepare!
I posted the rationale behind this over here: Why does code need to be reloaded in Rails 3?
If its bad to cross post the same answer, kindly let me know how its preferred to post an answer thats relevant to two questions...I'm happy to oblige.
As of newer Rails (> 4.0), I was able to reload class definitions, in console, for instance, with reload!.

How to mock the redirect to an external URL for a integration/acceptance test?

In my Rails 3 application I have a controller with the following actions (code simplified):
def payment
redirect_to some_url_of_an_external_website
end
# the external website redirects the browser to this action when the payment is done
def payment_callback
#subscription = Subscription.new(:subscription_id => params[:subscription_id])
...
end
In my acceptance test (using steak and RSpec 2), I want to avoid the redirection to this external URL when capybara follows the link pointing to the payment action. Basically I want to mock the route helper payment_path so that it directly points to the payment_call_path with the appropriate subscription_id parameter.
Is this the correct way to do it? If so, how can I mock the payment_path (could not find how to do it)?
Whilst I usually try to avoid mocking in integration tests, here you can do something like this:
MyController.stub!(:payment).and_return('payment received').
Using class_eval as mentioned above will lead to that method being permanently stubbed out across your entire run (if you want this, I'd suggest stubbing it in spec_helper [that's assuming you use a spec_helper]). I find using rspec's mocking/stubbing stuff preferable anyway.
I'm not sure if this is the 'correct' way of doing this, but you can stub any of your application's code to return what you need for your test. So somewhere in your RSpec test you can do something like
MyController.class_eval do
def payment
'payment received'
end
end
Here is an example (see section 'Session Helper Methods') where the #admin? method in ApplicationController is stubbed when a custom RSpec helper module is included into the example group.

How can I test common Rails controller behavior while staying DRY?

I've been writing RSpec tests for some Rails controllers and I've discovered a strong impulse to ensure that the Authlogic authentication is working properly. I also feel like I should be verifying that each action uses the same application-wide layout. However, writing tests for this behavior in every single action seems silly.
What I'd like to see are one-line matchers for filters and layouts, similar to Shoulda's matchers for associations and verifications. Unfortunately, no such matchers seem to be available (except for some Test::Unit macros for filters in this blog post). I'm tempted to just write them myself, but not being able to find anyone who's already done it makes me question whether or not a need for such matchers actually exists.
So my question is, how do you test your controllers' common behavior (if you test it at all), and would one-liner matchers testing filters and layouts be useful? Myself, I'm trying to decide between one-liners in the controller specs combined with speccing the filter explicitly, or just speccing the filter and ignoring the filters and layouts in the controllers (since they're only one line of code anyway).
I don't like the idea of writing specs for filters -- that seems too close to the implementation. If you had used TDD/BDD methods to build your controller from scratch, presumably you'd have written the action first, added some logic (e.g. to handle authentication) and then realized it should go into a filter instead. If your spec is along the lines of "Reject an index request if the current user is not the account user", your spec ought to be able to do something like (aircode):
current_user = Factory.create(:unauthorized)
controller.should_not receive(:index)
get :index
request.should redirect_to(some_safe_path)
And it doesn't matter whether the action is using a filter or not.
You can DRY up controller specs with Rspec macros. So (more hand-waving):
describe MyController do
should_reject_anonymous(self)
...
end
module ControllerMacros
def should_reject_anonymous(test_controller)
describe test_controller, "Authentication" do
it "rejects index" do
test_controller.should_not_receive(:index)
get :index
response.should redirect_to(some_safe_path)
end
end
end
end

Resources