Rails 3 'request_via_redirect' trouble - ruby-on-rails

I have a trouble with request_via_redirect
How i use this method:
def synchronize
request_via_redirect(:post, synchronize_companies_path, params)
end
And get an error:
NoMethodError (undefined method `request_via_redirect' for #<Companies::ApiController:0x00000006739a00>):
Anybody can explain what is wrong?

Seems like you are using a rspec integration method.
request_via_redirect, post_via_redirect and other methods like that are made to work with testing integration environment. Those functions only work inside a test/spec kind of file.
Try changing your code to the following:
def synchronize
require "uri"
require "net/http"
Net::HTTP.post_form(URI.parse(synchronize_companies_path), params)
end
I am pretty sure that there's a better way of doing what you want to do. Some more information about your intentions should help.

Related

IntegrationTest with Mocha, stub HelperMethod (Ruby)

I got a helper method:
has_permission?
In a Module called:
module ApplicationHelper
Inside app/helpers.
I also have an IntegrationTest which includes it:
include ApplicationHelper
My Integration test calls one of my controllers via get request.
On call I want to test if my integration test arrives at a certain method.
On this way is has to pass a few of the methods, one of those being the
has_permission?
In order to make sure this method passes I wanted to stub it.
Object.any_instance.expects(:has_permission?).returns(false)
Doesn't work
ApplicationHelper.expects(:has_permission?).returns(false)
Doesn't work either because it's not a static method.
Is there a way I can stub the helpers non-static method within the test so I can make it return false in all cases?
The test:
test "test try to edit without permission" do
#curr = users(:me)
sign_in #curr
SellingController.expects(:validate).never
post enable_update_user_selling_path(id: #user, params: {user: {sell: "1"}})
end
Stumbled across this when trying to work out how to stub an ApplicationHelper method in an ActionDispatch::IntegrationTest in Rails 5; not sure if that's exactly what you're trying to achieve but I ended up doing something like this
MyController.view_context_class.any_instance.expects(:my_method).returns(true)
It looks as though since Rails 5, helper methods aren't simply mixed into the controller classes directly hence the view_context_class bit.
Seems to work, hopefully this will be helpful to someone!
Forgot to post how I ended up solving this:
SellingController.any_instance.stubs(:has_permission?).returns(false)

Override method Ruby

I would like to override the method: authorize_endpoint_url from the Gem in a Rails application: https://github.com/AzureAD/omniauth-azure-activedirectory/blob/master/lib/omniauth/strategies/azure_activedirectory.rb
I tried to do it by adding a file to config/initializers/oauth.rb
With the code:
module OmniAuth
module Strategies
# A strategy for authentication against Azure Active Directory.
class AzureActiveDirectory
def request_phase
debugger
"www.hans.com"
end
end
end
end
But this approach doesn't seem to work, nothing get's actually overwriten. What do I wrong? Thank you
When writing "monkey patch" style alterations you'll want to ensure they're loaded correctly. One way to test this is, after all is said and done, to interrogate Ruby to find out which method is actually being used:
OmniAuth::Strategies::AzureActiveDirectory.instance_method(:‌​request_phase).sourc‌​e_location
The instance_method call returns an object with information about that method and the source_location property tells you where that was defined.
If if's your method, great, you got it loaded right. If not you may need to check that you're hooking in at the correct time.

How to extend World in the context of cucumber-rails?

I am building an API with Rails, using the rails-api gem. I want to use cucumber-rails and the gem 'Airborne' to test it.
Airborne comes with some nice helper methods for testing API responses, which I want to have access to in my step definitions. I have done this kind of thing before in Sinatra, which was relatively straightforward to configure in the /features/env.rb file.
It seems, however, that with rails-cucumber the creation of the 'World' happens behind the scenes somewhere and I don't know how to extend it to use the Airborne module after it's been created.
I have tried the following:
Airborne.configure do |config|
config.rack_app = Rails.application
end
Cucumber::Rails::World.extend(Airborne)
When(/^I make a request for information about an event$/) do
get "/events/1"
end
Then(/^I receive the information as a JSON$/) do
expect_json {}
end
I am still getting a NoMethodError on #expect_json, which is an Airborne method.
So my question is: how can I extend the instance of World in the context of cucumber-rails?
Don't panic, the World has been saved. The solution is to wrap Airborne and whatever else in a module:
module MyHelpers
include Airborne
include Capybara::DSL
end
Then pass that:
World(MyHelpers)

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.

Resources