Rspec:在 Devise::OmniauthCallbacksController 子类中测试重定向

问题描述 投票:0回答:4

按照 Devise 和 OmniAuth 上的 Railscast,我实现了一个

OmniauthCallbacksController < Devise::OmniauthCallbacksController
,其中包含处理 OmniAuth 回调的单个方法:

def all
  user = User.from_omniauth(request.env["omniauth.auth"])
  if user.persisted?
    sign_in_and_redirect user
  else
    session["devise.user_attributes"] = user.attributes
    redirect_to new_user_registration_url
  end
end
alias_method :facebook, :all

路线.rb:

devise_for :users, controllers: {omniauth_callbacks: "omniauth_callbacks", :sessions => "sessions" }

我想自定义它,所以我尝试使用 RSpec 来测试它。问题是如何测试这个方法和重定向?

如果在规范中我输入了

user_omniauth_callback_path(:facebook)
,它不会抱怨路线不存在,但似乎并没有实际调用该方法。

根据这个答案“控制器测试使用四个 HTTP 动词(GET、POST、PUT、DELETE),无论您的控制器是否是 RESTful。”我尝试了

get user_...
等,但这里确实抱怨该路线不存在。事实上,如果我这样做
rake routes
,它会显示该路由没有 HTTP 动词:

user_omniauth_callback [BLANK] /users/auth/:action/callback(.:format) omniauth_callbacks#(?-mix:facebook)

你能看到我错过了什么吗?

编辑

所以下面的这个问题调用该方法的一种方式是:

controller.send(:all)

但是我遇到了与提问者遇到的相同错误:

ActionController::RackDelegation#content_type delegated to @_response.content_type, but @_response is nil
ruby-on-rails rspec devise integration-testing omniauth
4个回答
5
投票

您需要做三件事才能完成此任务。

  • 进入OmniAuth测试环境
  • 创建 OmniAuth 测试模拟
  • 删除 from_omniauth 方法以返回用户

这是一个可能的解决方案,在规范本身中输入 (例如spec/feature/login_spec.rb)。 。 .

let(:current_user) { FactoryGirl.create(:user) }

before do
  OmniAuth.config.test_mode = true
  OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
    provider: :facebook,
    uid:'12345',
    info: {
      name: "Joe"
    }
  })
  User.stub(:from_omniauth).and_return(current_user)
end

我根据谷歌身份验证改编了此内容,因此 facebook 可能需要更多字段,但这些是 omniauth 文档需要的唯一字段。您应该能够通过查看数据库架构并查找与文档匹配的字段来找到正确的字段。

就我而言,最小值足以通过请求阶段并进入返回用户的存根方法。

此示例还使用了

FactoryGirl

可能并不完美,但希望对您有所帮助。祝你好运!

-丹


3
投票
如果你点击这个并且你正在运行

rspec 3.4这个例子应该适合你:

describe Users::OmniauthCallbacksController, type: :controller do let(:current_user) { FactoryGirl.create(:user) } before do OmniAuth.config.test_mode = true OmniAuth.config.mock_auth[:your_oauth_provider_here] = OmniAuth::AuthHash.new( provider: :your_oauth_provider_here, uid: rand(5**10), credentials: { token: ENV['CLIENT_ID'], secret: ENV['CLIENT_SECRET'] } ) request.env['devise.mapping'] = Devise.mappings[:user] allow(@controller).to receive(:env) { { 'omniauth.auth' => OmniAuth.config.mock_auth[:your_oauth_provider_here] } } allow(User).to receive(:from_omniauth) { current_user } end describe '#your_oauth_provider_here' do context 'new user' do before { get :your_oauth_provider_here } it 'authenticate user' do expect(warden.authenticated?(:user)).to be_truthy end it 'set current_user' do expect(current_user).not_to be_nil end it 'redirect to root_path' do expect(response).to redirect_to(root_path) end end end end
    

1
投票
我遇到了扭动问题

RSpec

 
OmniauthCallbacksController
,对此进行一些研究,它对我有用。这是我的代码,如果有人觉得有必要的话。测试是为了快乐的道路,它应该适用于新闻版本的
RSpec eg. 3.x


require 'spec_helper' describe OmniauthCallbacksController, type: :controller do describe "#linkedin" do let(:current_user) { Fabricate(:user) } before(:each) do OmniAuth.config.test_mode = true OmniAuth.config.mock_auth[:linkedin] = OmniAuth::AuthHash.new({provider: :linkedin, uid: '12345', credentials: {token: 'linkedin-token', secret: 'linkedin-secret'}}) request.env["devise.mapping"] = Devise.mappings[:user] @controller.stub!(:env).and_return({"omniauth.auth" => OmniAuth.config.mock_auth[:linkedin]}) User.stub(:from_auth).and_return(current_user) end describe "#linkedin" do context "with a new linkedin user" do before { get :linkedin } it "authenticate user" do expect(warden.authenticated?(:user)).to be_truthy end it "set current_user" do expect(subject.current_user).not_to be_nil end it "redirect to root_path" do expect(response).to redirect_to(root_path) end end end end end
    

0
投票
这是omniauthcontrollercallback,对我有用。

需要“rails_helper”

RSpec.describe Users::OmniauthCallbacksController,类型::controller do 描述“#google_oauth2” 之前做 request.env["devise.mapping"] = Devise.mappings[:user] 结束

context "with valid user" do let(:role) {Role.create!(name: 'candidate')} let(:user) {User.create!(email: '[email protected]', password: '123456', role_id: role.id, approved: true)} let(:auth) do OmniAuth::AuthHash.new({ provider: 'google_oauth2', uid: '123456', info: { email: user.email }, credentials: { token: 'token', expires_at: Time.now + 1.hour, refresh_token: 'refresh_token' } }) end before do request.env["omniauth.auth"] = auth end it "signs in the user and redirects to the root path" do expect(User).to receive(:from_omniauth).with(auth).and_return(user) expect(user).to receive(:persisted?).and_return(true) expect(user).to receive(:save!) get :google_oauth2 expect(flash[:notice]).to eq(I18n.t("devise.omniauth_callbacks.success", kind: "Google")) expect(user.access_token).to eq(auth.credentials.token) expect(user.expires_at.utc.to_s).to eq(auth.credentials.expires_at.utc.to_s) expect(user.refresh_token).to eq(auth.credentials.refresh_token) expect(response).to redirect_to(root_path) end end context "with invalid user" do let(:auth) { OmniAuth::AuthHash.new(provider: 'google_oauth2', uid: 'invalid') } before do request.env["omniauth.auth"] = auth end it "redirects to the new user registration page" do expect(User).to receive(:from_omniauth).with(auth).and_return(User.new) expect_any_instance_of(User).to receive(:persisted?).and_return(false) get :google_oauth2 expect(session["devise.google_data"]).to eq(request.env["omniauth.auth"]) expect(response).to redirect_to(new_user_registration_url) end end
结束
结束

© www.soinside.com 2019 - 2024. All rights reserved.