I have been having a problem with my Rails api.
The offender:
context 'as a publisher' do
before { create(:invitation_post) }
it 'shows posts whose invitations are to you' do
authorise publisher # helper which adds an authentication token to the request headers
get :index, params: { expand: ['invitation'] }
expect(json_body[:data].map {|e| e[:invitation][:account] }).to all eq account.id
end
end
And the error (because the response is a 403):
Failure/Error: expect(json_body[:data].map {|e| e[:invitation][:account] }).to all eq account.id
NoMethodError:
undefined method `map' for nil:NilClass
I have run rspec
with --bisect
, which helped me to identify a pair of examples I can run to reproduce it, which at least saves me running ~300 other tests each time. But the other example seems quite unrelated, from a different controller and test file.
I have pinpointed the point at which it fails - in my policy. I check the type of user (some single-table inheritance going on) with user.is_a?(Publisher)
, which should return true, but in this one particular instance it doesn't. However, if I say user.class.name == 'Publisher'
, that does return true.
I have p
'd the user in both the test and the policy, and they appear to be completely identical.
Extra info (and I'd be happy to share more info where necessary):
config.use_transactional_fixtures = true
- have tried bothtrue
andfalse
- doesn't seem to fix it.- Test data from FactoryBot (
gem "factory_bot_rails", "~> 4.0"
) - Have tried cleaning the db at various points with
DatabaseCleaner
, but also doesn't seem to fix - The policy:
def index?
user.is_a?(Admin) || user.is_a?(Author) || user.is_a?(Publisher)
end
So I suppose what I'm asking is - if the user isn't a Publisher, then what could it be? And what might I need to do to fix the test? Any help or light which could be shed would be much appreciated!
EDIT
The other test from the bisect:
it 'returns a list of invitations' do
get :index
expect(json_body[:data].count).to eq 4
end
The authorise helper:
def authorise(user)
request.headers.merge!({ "Authorization" => JsonWebToken.encode(user_id: user.id) })
end