ruby on rails - Request spec order dependent failure (wrong SQL created for devise user update on login) -
we face problem when request spec fails (typo or other exception) affects other request specs should unaffected. problem use many gems tried create minimal reproduction app (without success, https://github.com/tak1n/reproduction)
the problem in detail:
we have request spec need login user. user authentication use devise , therefore use warden::test::helpers log in users in request specs. devise automatically updates user related attributes when user logs in (last_sign_in_at, last_sign_in_ip etc..).
the problem here when tries save user doing changes end result insert user instead of update user , therefore crashes.
here example spec our app:
require 'rails_helper' rspec.describe 'suggestions api' let(:user) { factorygirl.create(:user, :professional) } before login(user) # same in https://github.com/tak1n/reproduction/blob/master/spec/support/request_macros.rb#l6 end describe '/suggestions.json', :vcr context 'with non saved filter' # setup stuff here (setup proper objects in db) # params defined here through let(:params) { ... } 'returns proper suggestions' suggestion.refresh! '/suggestions.json', paramst expect(json.count).to eq(2) expect(json.first['id']).to eq(sug2.id) expect(json.second['id']).to eq(sug1.id) end end context 'with saved filter' # setup stuff here (setup proper objects in db) # params defined here through let(:params) { ... } 'returns proper suggestions' suggestion.refresh! '/suggestions.json', params expect(json.count).to eq(2) expect(json.first['id']).to eq(sug2.id) expect(json.second['id']).to eq(sug1.id) end end end end
the result of should first spec fails because of typo paramst
, affects second spec:
here spec run: https://gist.github.com/tak1n/102c1aa121b66e0ab56602b76f911ec0
i tried dig deeper , saw logic whether save creates or updates record depending on https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb#l85
next tried output @new_record
in case.
def new_record? sync_with_transaction_state puts "new record: #{@new_record}" if self.class == user @new_record end
i got following: https://gist.github.com/tak1n/330560a3a108abc8fce4d105a48ac444
when specs run in different order (non failing first spec typo or exception in it) got this: https://gist.github.com/tak1n/6eb24693226d8e6a713c0865ea1bebd5
the difference here "working" spec run new record: <boolean>
different. when spec exception runs before new record becomes true , therefore generates sql create new record.
next assumed gems causing problem, thought database_cleaner in reproduction more or less same , there works.
the problem i'm stuck @ debugging , not sure proceed. i'm not sure gem or our code causing this.
feel free ask questions if need further details, in advance.
seems issue caused devise-async (https://github.com/mhfs/devise-async).
see https://github.com/rails/rails/issues/26038 , https://github.com/mhfs/devise-async/issues/96 more information.
Comments
Post a Comment