Первопроходческие ячейки и разработка current_user в RSpec
Trailblazer рекомендует делать инъекции current_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. Обычный метод на основе контроллера не работает, так как нет доступа к запросам.
Кстати, я попробовал решение "Разработать насмешку", но оно не сработало:
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 ответ
В документации 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 вам больше подойдет, они несколько похожи на ячейки, но более доступны для интеграции рельсов с рельсами, в то время как trailblazer рассматривает рельсы как необязательные.
https://trailblazer.zulipchat.com/, если кто-то наткнется на эту тему и захочет напрямую спросить основную команду об этом подходе, они довольно активны в zulipchat, но зная их, они просто посоветуют не делать этого, поскольку это против для чего был разработан инструмент, как указано в документации.