Testing facebook login with rails cucumber - ruby-on-rails

I have set up Facebook login on my site following this tutorial and am using cucumber and capybara. I have tried following other SO posts like this that explain how to set up a fake login account. If I use this directly, I get:
When I follow "sign_in" # features/step_definitions/web_steps.rb:56
No route matches [GET] "/oauth/authorize" (ActionController::RoutingError)
./features/step_definitions/web_steps.rb:57:in `/^(?:|I )follow "([^"]*)"$/'
features/facebook_signin.feature:9:in `When I follow "sign_in"'
If I add get "/oauth/authorize" to my routes, I get:
When I follow "sign_in" # features/step_definitions/web_steps.rb:56
uninitialized constant OauthController (ActionController::RoutingError)
./features/step_definitions/web_steps.rb:57:in `/^(?:|I )follow "([^"]*)"$/'
features/facebook_signin.feature:9:in `When I follow "sign_in"'
I don't know what is going on and why it is complaining. If I change my Gemfile from gem 'omniauth-facebook', '1.4.0' to just gem 'omniauth-facebook' I get virtually the same errors above except instead of:
/oauth/authorize, I get /dialog/oauth and instead of uninitialized constant OauthController, I get uninitialized constant DialogController
Has anyone recently successfully set up cucumber testing for login with Facebook?
When I am on localhost:3000 and navigate to localhost:3000/auth/facebook everything works and I am using a sessionsController so I don't understand why in testing, it is trying to use these oauthControllers or DialogueControllers.

I recently had the same issue or a very similar issue:
ActionController::RoutingError:
No route matches [GET] "/dialog/oauth"
I had taken the working specs which properly set up mock responses from another project and was pretty surprised to suddenly get this error.
After much pain and suffering I had a major facepalm moment when I realized i had forgot to set OmniAuth to use test mode:
# spec/rails_helper.rb
OmniAuth.config.test_mode = true
This will cause OmniAuth to short circuit so that you can set the auth responses by:
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
:provider => 'facebook',
:uid => '123545'
# etc.
})
I think the error is due to OmniAuth trying to be helpful by using the :developer strategy in the test environment so that you don't get banned by the auth provider.
See https://github.com/intridea/omniauth/wiki/Integration-Testing.

Have you enabled Javascript in this tests? As the tutorial mentions the facebook.js.coffee?
describe 'When I follow "sign in"', js: true do
Another possibility is that you included the gem only in the development block of the Gemfile
group :development do
gem 'omniauth-facebook'
end
BTW: you shouldn't be testing against "real" external endpoints. Take a look at webmock for this kind of tests to mock the Facebook response

I had to put #omniauth_test_success before the feature and not the step definition. Additionally, I had to fix some routing issues. Will post full report later this week.

Related

Integration Testing with Devise + Omniauth + Rspec + Capybara

I am trying to write some integration tests using Rspec (feature) alongside Devise and Omniauth. The OAuth provider I am using is azure_activedirectory.
I have followed the tutorial here at the Omniauth wiki
I don't think I am doing it right. When I launch an integration test, the link for the login (localhost:3000/omniauth/azure_activedirectory) behaves like it would in dev or production, with the link directing the client to the omniauth portal page.
Of course given this is a test, I can't store credentials here.
It appears from the code in the wiki link that it should instead feed a login using a mock_auth.
Here is my current spec code:
require 'rails_helper'
Capybara.app_host = "http://lvh.me"
OmniAuth.config.test_mode = true
OmniAuth.config.add_mock(:azure_activedirectory, {:uid => '12345'})
RSpec.feature "AuthenticatesUser", type: :feature do
before do
Rails.application.env_config["devise.mapping"] = Devise.mappings[:user]
Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:azure_activedirectory]
end
scenario "User can login", js: true do
WebMock.allow_net_connect!
visit '/'
click_link 'login'
binding.pry
WebMock.disable_net_connect!(allow_localhost: true) # Re enable with local host
end
end
So what am I doing wrong? I feel that I am using the example code in a very incorrect way or not understanding the process.
Or is the next step just setting up a testing oauth instance and configuring it that way to use live credentials from Azure.
Thanks for the help in advance.
UPDATE
This has to do with Capybara and the JS driver starting or running on a different server.
If in the interactive ruby console in the Selenium browser OmniAuth.config.test_mode == false. If I set it using the console in the web browser, everything 'works'.
I found the solution.
You can not put OmniAuth into test mode in your specs. As capybara with js is in a separate thread, it has no idea about any config that was being set in the specs.
The solution was moving the declarations
OmniAuth.config.test_mode = true
OmniAuth.config.auth_mocks = NewAuthMock
into the test.rb environment file, that way Capybara would spawn with the correct config.

Connecting with Quickbooks: Oauth Troubles, GrantUrl Error using qbo_api

Possible duplicate of Ruby on Rails integration with Quickbooks not working
I realize that this is a purely coding related error. I am unable to get my rails app to connect to Quickbooks due to my limited understanding of rails framework right now. Using this gem https://github.com/minimul/qbo_api, I got the button on my web app. However I still get a Routing error with my granturl section of code.
the command ruby App.rb from my console works very well. But integrating the Sinatra code in my rails app leads to this error.
This is my HomeApp.rb in config/initializers
class HomeApp < Sinatra::Base
require "bundler/setup"
require 'sinatra'
require 'json'
require 'openssl'
require 'base64'
require 'omniauth'
require 'omniauth-quickbooks'
require 'dotenv'
require 'qbo_api'
Dotenv.load "#{__dir__}/../.env"
PORT = 3000
CONSUMER_KEY = 'blah blah'
CONSUMER_SECRET = 'blah blah'
set :port, PORT
use Rack::Session::Cookie, secret: '34233adasf'
use OmniAuth::Builder do
....
....
end
In my config.ru I have the following
require ::File.expand_path('../config/environment', __FILE__)
run Rails.application
Dynopoker.configure do |config|
config.address = 'http://wakemydyno.com'
require "HomeApp"
The control passes to my index.erb file successfully but the error is thrown at this point
<script>
intuit.ipp.anywhere.setup({
grantUrl: "http://localhost:<%= #port %>/auth/quickbooks",
I use rails 4 and ruby 2 and my error says
No route matches [GET] "/auth/quickbooks"
Good thing, I was allowed to stew in my own stupidity while realizing the answer to this solution.
So I changed my routes.rb as follows:
Rails.application.routes.draw do
get "/" => HomeApp, :anchor =>false
match '/auth/:provider/callback' => 'quickbooks#callback', via: [:get,:post]
Also I removed the
'require HomeApp'
line from my config.rufile.
Basically I created a quickbooks controller and added the callback.html.erb file for a callback action inside the controller. instead of using the Sinatra app for the callback, my code uses this quickbooks route just for the callback. The rest of the code flows solely from the Sinatra code.
No clue if this is the right approach to using the gem. But since it works, I am sticking with it for now.

Is it possible to call GET in a Capybara/Rspec integration test?

I have a Rails 4.2 application....I was adding content compression via this thoughtbot blog post, but I get an error such as:
undefined method `get' for #<RSpec::ExampleGroups::Compression:0x00000009aa4cc8>
Perusing over the capybara docs, it seems like you shouldn't be using get. Any idea how to test the below then in Rails 4?
# spec/integration/compression_spec.rb
require 'spec_helper'
feature 'Compression' do
scenario "a visitor has a browser that supports compression" do
['deflate','gzip', 'deflate,gzip','gzip,deflate'].each do|compression_method|
get root_path, {}, {'HTTP_ACCEPT_ENCODING' => compression_method }
response.headers['Content-Encoding'].should be
end
end
scenario "a visitor's browser does not support compression" do
get root_path
response.headers['Content-Encoding'].should_not be
end
end
In a capybara test you would use visit not get (as described here), but that answer won't actually help you because the test you've written above is not an integration test, it's a controller test.
Move it to spec/controllers and use the controller-specific helpers describe/context/it etc. to construct your tests for your controller. You can set the headers and do the sorts of checks that you're doing in the code you're showing.

How can I fix this undefined method error?

I am integrating Postmark's transactional email service into my web application so that when a user signs up, my application sends the user a welcome email. When I try to signup as a user, I get the following error: undefined method `postmark_settings=' for ActionMailer::Base:Class
In my config/application.rb file, I have the following code:
config.action_mailer.delivery_method = :postmark
config.action_mailer.postmark_settings = { :api_key => "my_api_key" }
I'm not sure what is causing the error or how I can go about fixing it. If I haven't provided enough useful information to solve the problem, just let me know and I'll add whatever code might be useful. Thanks so much!
Have you included the line below in your Gemfile?
gem 'postmark-rails', '0.4.0'
There are similar issues where people haven't included this line on the Gemfile...
Also, are you using Rails 3? The configuration in different between Rails 2 and 3. Please note details here.

Authlogic_OAuth fails with error "uninitialized constant UserSession::OAuth" in Rails 3

I've gotten my application to work (i.e. sign_in and sign_up) with Authlogic and I'm now trying to add support for OAuth through the Authlogic_OAuth gem. I've gotten all of the basics set up (I think) and I've added a "Login with Twitter" button to my landing page. The problem is that when I click the button I get this error:
uninitialized constant UserSession::OAuth
with the application trace:
app/models/user_session.rb:17:in `oauth_consumer'
app/controllers/user_sessions_controller.rb:23:in `create'
The function that is failing is in my user_session model:
# authlogic_oauth hacks
# Twitter example
def self.oauth_consumer
OAuth::Consumer.new("TOKEN", "SECRET",
{ :site => "http://twitter.com",
:authorize_url => "http://twitter.com/oauth/authenticate"})
end
I'm pretty new to rails and ruby so I don't quite understand where this namespace collision is coming from or how to solve it. Any help would be greatly appreciated.
OK, I figured it out. The problem is that OAuth::Consumer is not defined withing authlogic_oauth. It's actually defined in the oauth gem. so I updated my Gemfile to:
gem 'authlogic', '2.1.6'
# set up oauth capabilities. Note: :lib is replaced with :require in rails 3
gem 'authlogic-oauth', '1.0.8', :require => 'authlogic_oauth'
gem 'oauth', '0.4.4'
then run:
bundle install
and, don't forget to restart the rails server so that it reloads the gems from the Gemfile.
Try to change OAuth to ::OAuth. The colons mean that you want to access OAuth from outside your class. It was searching from your class.

Resources