Functional test "get" requests and the https protocol - ruby-on-rails

I'm trying to write a functional test for an action that must run over https. I'm not testing the HTTPS redirect - I already know that works from another test.
What I'm trying to do is:
get :new, :protocol => "https://"
assert_redirected_to :root
But this does not issue the request over https. Is there a "get" option that will allow me to change the protocol?
Also, if I try to specify the url (e.g.: get "https:/test.host/do/something") I get a routing error, since there's no route at my rails level for https - it's taken care of at my web server level.

I found a much simpler answer here:
http://railspikes.com/2008/9/12/testing-ssl
Which is to put the following line either (a) at the beginning of each functional test where SSL is needed, or (b) in the 'setup' method if every action in a controller uses SSL.
#request.env['HTTPS'] = 'on'
This prepends all requests with https

In functionnal test, there are no routing from HTTP or anything else, it's use directly the controller. So you can't test that become from HTTP or HTTPS.
But you can mock the request.protocole dans define it like 'https'
request.stub(:protocol).and_return("https://")
get :new

Related

devise confirmation_url in HTTPS

My website is entirely SSL, so I would like to have also the urls generated by devise (3.2.2) for Email verification to be https://....
currently the urls are generated by:
confirmation_url(#resource, :confirmation_token => #token)
which produces nice urls like:
http://example.com/users/confirmation?confirmation_token=zqfHS35ckLQZscSbsgMm
I would like the url to be
https://example.com/users/confirmation?confirmation_token=zqfHS35ckLQZscSbsgMm
Also, currently the email verification doesn't work, because nginx operates a redirect to the https equivalent to every page, and for some reasons things get messed up and the https version is a corrupted url, like:
https://example.com/users/confirmation?confirmation_token=zqfHS35ckLQZscSbsgMm?confirmation_token=zqfHS35ckLQZscSbsgMm
for some reasons nginx redirects to this corrupted url, so Unicorn can't but reject the request.
any clues?
You can either specify the protocol in the email template, as you did in your own answer, or you can specify it as a default in the mailer. The simplest way to do this, if you are happy for all emails to use https links, is to add it to your app config. For example, in your production.rb:
config.action_mailer.default_url_options = {:protocol => 'https', :host => 'example.com'}
I know it doesnt matter any more if you're going straight to https, but your url after the nginx redirect from http to https looks like it's appending the query string to the entire url, so it would be worth fixing that so it works in all cases even if you don't need it for the emails any more. If you're using a return 301 … statement in the nginx config, perhaps there's a trailing $query_string or $args you don't need - for example, if you're using $request_uri that already has the GET parameters in it.
Also, I don't think you will find confirmation_url defined directly anywhere. If you try rake routes you'll probably see one of them is:
user_confirmation GET /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"show"}
which means that there will automatically be a user_confirmation_url helper available as with routes in general. I think devise then allows you to use confirmation_url due to its clever tracking of the scope you're using ('user' in this case), though I must admit I haven't looked at the code enough in devise's routing to know exactly how it does it for the routes.
I changed the method call to:
confirmation_url(#resource, :confirmation_token => #token, protocol: "https")
and that started generating correctly the urls with https as required.
I couldn't find the definition of confirmation_url anywhere in the devise code though.

rails get app root/base url

In my app I have a few APIs that under api domain. Now in one of the API I want to generate a url that pointing to the main domain, say
test.com/blabla...
I tried to use url_for but seems the default root_url or request.host is in api domain. Url_for will make it to be
api.test.com/blabla..
while I want it to be
test.com/blabla...
Url_for can take a parameter
host: ...
to set it to be test.com/, the question is how can I get the root/base url (test.com) for host? root_url or request.host are all api.test.com.
Any ideas? Thanks.
Just so that it's useful to someone else , i came across this today
request.base_url
gives the full path in local as well as on live .
request.domain
gives just the domain name so it sometimes kinda breaks the link while redirecting
According to this you can do request.domain
Simplest alternative method:
include in you're class
include Rails.application.routes.url_helpers
create function or just use root_url to get app root/base url:
def add_host_prefix(url)
URI.join(root_url, url).to_s
end
finally: add
Rails.application.routes.default_url_options[:host] = 'localhost:3000'
in:
Your_project_root_deir/config/environments/development.rb
although helpers can be accessible only in views but this is working solution.
request.domain fails on CF it given domain url not base url

How do I ignore a route in rails?

I have a route i.e. mysite.com:3000/new_route that I'd like to ignore, is this possible to do through rails and not server side?
I've read that this can be done through apache, however, my app is running on Heroku and that type of control isn't accessible to me. Therefore, I'm looking for another way to do this through Rails.
Thanks
update
I am using faye to have live notifications in my app, on localhost faye runs on port 9292 - localhost:9292/faye, all good in development mode, but in production it should point to mydomain.com/faye, there are no port numbers in production environment, and loading faye.js returns error not found
If you're talking about a resources route you don't want to be created:
resources :something, except: :new
However, I'm not exactly sure if this is what you meant by ignore.
You can define a route at the top of your routes.rb file that will redirect to some other page.
get '/new_route', redirect: '/'
By the time you ask Rails to process the route, it is already too late. If you ask rails to process a route, it will, either by returning a 404 of 500 error, or a page.
If you want the route to be processed by another application, it will need to be intercepted by your webserver (nginx or apache, or whichever one you're using). In their configuration, you just redirect that route to the other application, and every other route to the Rails app.
EDIT
Another option you have, is to forward your requests to a different server.
You add a route like
get 'faye/*query' => 'faye#get'
post 'faye/*params' => 'faye#post'
And then a controller
require 'faraday'
class FayeController < ApplicationController
APP = 'http://mydomain.com:9292'
def get
request_page :get
end
def post
request_page :post
end
private
def request_page(method)
conn = Faraday.new(:url => APP)
query = params.delete(:query)
response = conn.send method, query, params
render text: response.body.gsub(APP, 'mydomain.com/faye')
end
end
which will use Faraday to load the information from your other application.

Rails/Rack: retrieving request params from within canonical_host middleware

I'm using the Rack Canonical Host middleware (https://github.com/tylerhunt/rack-canonical-host) with Rails to force the www for all root requests (example.com becomes www.example.com). However, if a visitor is attempting to access a valid subdomain of our app, we obviously don't want to force www. Here's the example usage of the middleware:
Rails.application.config.middleware.use Rack::CanonicalHost do
# the following return value will be used to set the canonical host
'www.example.com'
end
As you can see it's somewhat static, which is a problem. However, if I had access to the request parameters (eg subdomain, domain, etc) I could check against them, and redirect accordingly (and only if need be).
Anyone have any pointers?
Specify a parameter for this block
Rails.application.config.middleware.use Rack::CanonicalHost do |params|
puts "PATH_INFO #{params['PATH_INFO']}"
end

How should I test request-related logic in Rails development?

I have several before_filters defined in my application controller to handle requests I don't like. One representative example is:
before_filter :reject_www
private
def reject_www
if request.subdomains.include? 'www'
redirect_to 'http://example.com' + request.path, :status => 301
false
end
end
(Returning false skips any following before_filters and simply returns the redirection immediately)
So, two questions:
One, how should I test this functionality? The only testing framework I've used so far is Cucumber + Webrat, which isn't really set up to handle this kind of thing. Is there another framework I should also use to fake requests like this?
Two, is there any way I can try out this functionality myself in my development environment? Since I'm simply browsing the site at localhost:3000, I can't ensure that the above code works in my browser - I'd have to push it to production, hope it works and hope it doesn't mess up anything for anyone in the meantime, which makes me nervous. Is there an alternative?
In a functional test, you can explicitly set the request host. I'm not sure what testing framework you prefer, so here is an example in good ole' Test::Unit.
def test_should_redirect_to_non_www
#request.host = 'www.mydomain.com'
get :index
assert_redirected_to 'http://mydomain.com/'
end
To address #2
You can add entries in your hosts file so that www.mydomain.com points to your local host and then test the logic in your development environment .
You can try hosting it using passenger so that it works on apache .
Hope that helps .

Resources