RSpec中的Trailblazer Cells和Devise current_user

时间:2017-06-22 05:11:20

标签: ruby-on-rails rspec devise trailblazer

开拓者recommendscurrent_user注入单元格,就像这样

<%= concept(Appointment::Cell::UserStatus,user,current_user: current_user) %>

然后可以使用方法

使其在单元格内可访问
  def current_user
    options[:current_user]
  end

但是,这意味着在每次调用单元格时添加此注入,而事实上current_user是一个特殊的全局变量。

我设法通过创建超类单元来注入current_user,如下所示:

class Template::Cell < Cell::Concept
  include Pundit
  include Devise::Controllers::Helpers

  Devise::Controllers::Helpers.define_helpers(Devise::Mapping.new(:user, {}))
  include Escaped
  include ActionView::Helpers::JavaScriptHelper
end

这很有效,除了我在RSpec测试期间无法登录用户。通常的基于控制器的方法无法工作,因为无法访问请求。

顺便说一下,我尝试过&#34;设计嘲笑&#34;解决方案,但它没有工作:

RSpec.describe Friendship::Cell, type: :cell do
  include Devise::TestHelpers
  include ControllerHelpers
  let!(:user) { create :user }

  describe '#methods' do
    before do
      sign_in(user)
    end
    subject { concept(described_class, user, current_user: user) }
    it { expect(current_user).to eq(user) }
  end
end

module ControllerHelpers
  def sign_in(user = double('user'))
    if user.nil?
      allow(request.env['warden']).to receive(:authenticate!).and_throw(:warden, {:scope => :user})
      allow(controller).to receive(:current_user).and_return(nil)
    else
      allow(request.env['warden']).to receive(:authenticate!).and_return(user)
      allow(controller).to receive(:current_user).and_return(user)
    end
  end
end

错误

1) Friendship::Cell cell can be instantiated
     Failure/Error: @request.env['action_controller.instance'] = @controller

     NoMethodError:
       undefined method `env' for nil:NilClass
     # /Users/sean/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/devise-4.3.0/lib/devise/test/controller_helpers.rb:40:in `setup_controller_for_warden'
     # /Users/sean/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/rspec-rails-3.6.0/lib/rspec/rails/adapters.rb:165:in `block (2 levels) in setup'

1 个答案:

答案 0 :(得分:0)

文档 https://trailblazer.to/2.0/gems/cells/getting-started.html#discussion-navigation 说:

It is important to understand that the cell has no access to global state. You as the cell author have to define the interface and the dependencies necessary to render the cell.

与你的话相反:

However, this means adding this injection on every call to a cell, when in fact current_user is a special global var.

我认为您误解了开拓者细胞的目标。他们不应该有权访问应用程序的全局状态。它们是独立的实体,依赖于依赖注入。

如果您希望单元格能够访问全局状态,您实际上可能正在为此寻找不同的工具。也许 https://github.com/github/view_component 会更适合你,它们有点类似于单元格,但更易于与 rails 集成,而开拓者将 rails 视为可选。

https://trailblazer.zulipchat.com/ 如果有人偶然发现这个话题并想直接向核心团队询问这种方法,他们在 zulipchat 上非常活跃,但了解他们,他们只会建议不要这样做,因为这与工具是为文档指定的。