Trailblazer recommends injecting current_user
into the cell, like this
<%= concept(Appointment::Cell::UserStatus,user,current_user: current_user) %>
One could then make it accessible within the cell using a method
def current_user
options[:current_user]
end
However, this means adding this injection on every call to a cell, when in fact current_user
is a special global var.
I've managed to get around having to inject current_user
by creating a superclass cell, like this:
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
This works well, except I cannot work out to sign in a user during RSpec testing. The usual controller-based method doesn't work as there is no access to requests.
By the way, I tried the "Devise mocking" solution, but it didn't work:
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
Error
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'