Mechanize: not logged in the site - ruby-on-rails

I'm trying to authorise to other site with gem mechanize
My code:
def login_zenit
agent = Mechanize.new
agent.get('http://mobile.zenitbet.com/') do |p|
f = p.forms.first
f.login = 'login'
f.fields[1].value = 'password'
f.submit
end
agent.get('http://mobile.zenitbet.com/')
redirect_to root_url
end
The problem is when I run login_zenit it doesn't work - I'm not authorising to the site in web browser. Although if I run this code in rails console it works perfectly. Where did I make a mistake? maybe there is a problem with redirect_to root_url?
Thanks!

In general is not possible. For this to work visiting your app would need to set the appropriate cookies for mobile.zenibet.com.
You do have those cookie values - they're inside the mechanize object, but even if you were to extract them you wouldn't be able to set them on the correct domain. If your app is being served from foo.com then the browser will let you set cookies on foo.com or any subdomain of it, but it won't let you set cookies on another arbitrary domain (see point 5 in section 5.3 of the rfc)
Unless your app runs on a subdomain of zenibet.com I think you are out of luck

Related

Selenium/Watir: 'InvalidCookieDomain' error when trying to add cookie

I am new into WATIR, or Selenium, but I was trying to add a cookie into my WATIR browser, as below:
browser = Watir::Browser.new :firefox
browser.goto(url)
browser.cookies.add name,value, domain: ".www.example.com"
I am prompted with the following error:
Selenium::WebDriver::Error::UnknownError: ReferenceError: InvalidCookieDomainError is not defined
But, when I delete the domain option, it works.
I was wondering why I can't add a different domain into my cookies?
Like WATIR, all Selenium-based frameworks create language-specific wrappers to Selenium pre-defined commands. These commands are defined here in the Selenium Webdriver W3C standard.
If you go to Cookies section, specifically, the addCookie sub-section, you will see the following:
If the current browsing context’s document element is a cookie-averse Document object, return error with error code invalid cookie domain.
Your domain attribute is bound to the same domain as your given url. So, basically, your domain HAS to be the same as your current url, or a sub-domain of the url.
Example: For url=global.nba.com, you can set cookies for both the sub-domain ({domain: "global.nba.com"}), as well as for the root-domain ({domain: "nba.com"}).
browser = Watir::Browser.new :firefox
browser.goto(url)
browser.cookies.add("<yourCookieName>","<yourCookieValue>", {domain: "<sameUrlOriginDomain>"})
Hope this helps!
in my case i had to go to the url first before setting a cookie, e.g.
visit root_path
('f'..'k').each.with_index do |cookie, index|
Helper::Browser.set_cookie(:esid, cookie)
visit root_path
end

Getting full URL as displayed in browser URL bar

I have a rails app where I want to send people an email when they sign up. The email has a link to their photos portal so they can get started adding photos, etc..
class MyMailer < ActionMailer::Base
def welcome_email
# ...
link = photos_url # => www.myapp.com/photos
# ...
end
end
The problem is that when I push my code to Heroku and run it live, that link doesn't generate as expected.
The photos_url returns the URL relative to the localhost and ends up generating myapp.herokuapp.com/photos, which is incorrect.
What's even stranger is that if I pause the code at that point with binding.pry and try to see what photos_url is returning, it correctly returns www.myapp.com/photos as expected.
Any thoughts on how to resolve this? I'd hate to have to construct the URL myself from scratch, because that means I have to do it for every environment (localhost, staging, production, etc...)
Thanks!
ActionMailer isn't tied to the request/response cycle, thus it doesn't know what's the host the app is currently running on. Actually, emails are typically sent by some background worker processes which know nothing about the current request URL.
So to make it work you need to set the ActionMailer default_url_options.host option.
Add this into you config/environments/production.rb:
config.action_mailer.default_url_options = { host: 'www.yourapp.com' }

Rails, Devise and Dynamic Subdomains on Subdomain (e.g. user.beta.example.com) how to setup?

I'm using basecamp style subdomains, rails 3.2, devise 2, passenger standalone. Everything is working fine on *.example.com. Now i want to launch a staging environment on *.beta.example.com and not sure whats the best way to make it work.
The following method checks if user requests app.example.com (then he is redirected to sign in page) or someone's account (e.g. user1.example.com), otherwise badrequest is returned. (app_subdomain = 'app')
def validate_subdomain
if request.subdomain == Settings.app_subdomain
redirect_to(user_signed_in? ? users_accounts_path : new_user_registration_path)
else
head :bad_request unless current_account?
end
end
If i deploy it to *.beta.example.com then request.subdomain returns "app.beta" and validations no longer work.
What would be the most elegant and reusable way to solve it? Other than to strip environment's subdomain manually. Thanks
Option one: change request.subdomain to request.subdomains.first. Then only app from app.bla-bla-bla.anything.example.com will be recognized.
Option two: set config.action_dispatch.tld_length in config/environments/production.rb. Sets the TLD (top-level domain) length for the application. Defaults to 1.
Source on tld_length:
Rails 3.x TLD length
http://guides.rubyonrails.org/configuring.html
https://rails.lighthouseapp.com/projects/8994/tickets/5215-configurable-tld_length-for-subdomains

Rails for dev, beta, staging and production, get the proper domain name out from api subdomain

In my previous question, I wanted to get the base url from api subdomain, eg.
api.test.com
this can be done by
request.domain
However, if I have different environment as subdomain, say
api.dev.test.com, api.beta.test.com, api.staging.test.com...
then request.domain will give me
test.com
instead of
dev.test.com, beta.test.com....etc.
Any solution to get the proper domain? root_url, request.host, request.referer won't work in this case. Should I check the environment and set the domain/host in some configuration file when loading?
Thanks.
From the Rails doc....
domain(tld_length = ##tld_length)
Returns the domain part of a host, such as “rubyonrails.org” in “www.rubyonrails.org”. You can specify a different tld_length, such as 2 to catch rubyonrails.co.uk in “www.rubyonrails.co.uk”.

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