# frozen_string_literal: true describe DossierSearchService do describe '#matching_dossiers' do let!(:dossiers) { Dossier.where(id: dossier.id) } before { perform_enqueued_jobs(only: DossierIndexSearchTermsJob) } def searching(terms, with_annotations: false) described_class.matching_dossiers(dossiers, terms, with_annotations) end describe 'ignores brouillon' do let(:dossier) { create(:dossier, state: :brouillon) } it { expect(searching(dossier.id.to_s)).to eq([]) } end context 'with a dossier not in brouillon' do let(:user) { create(:user, email: 'nicolas@email.com') } let(:etablissement) { create(:etablissement, entreprise_raison_sociale: 'Direction Interministerielle Du Numérique', siret: '13002526500013') } let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :text }], types_de_champ_private: [{ type: :text }]) } let(:dossier) do create(:dossier, procedure:, state: :en_construction, user:, etablissement:).tap do |dossier| dossier.project_champs_public.first.update!(value: 'Hélène mange des pommes') dossier.project_champs_private.first.update!(value: 'annotations') end end it do expect(searching('')).to eq([]) # by dossier id expect(searching(dossier.id.to_s)).to eq([dossier.id]) # annotations is unsearchable by default expect(searching('annotations')).to eq([]) # but can be searched with the with_annotations option expect(searching('annotations', with_annotations: true)).to eq([dossier.id]) # by email expect(searching('nicolas@email.com')).to eq([dossier.id]) expect(searching('nicolas')).to eq([dossier.id]) # by SIRET expect(searching('13002526500013')).to eq([dossier.id]) expect(searching('1300')).to eq([dossier.id]) # by raison sociale expect(searching('Direction Interministerielle Du Numérique')).to eq([dossier.id]) expect(searching('Direction')).to eq([dossier.id]) # with multiple terms expect(searching('Direction nicolas')).to eq([dossier.id]) # with forbidden characters expect(searching("'?\\:&!(Direction) ")).to eq([dossier.id]) # with a single forbidden character should not crash postgres expect(searching('? Direction')).to eq([dossier.id]) # with supirious spaces expect(searching(" nicolas ")).to eq([dossier.id]) # with wrong case expect(searching('direction')).to eq([dossier.id]) # by champ text expect(searching('Hélène')).to eq([dossier.id]) # by singular expect(searching('la pomme')).to eq([dossier.id]) # without accent expect(searching('helene')).to eq([dossier.id]) # NOT WORKING YET # with a single faulty character expect(searching('des pammes')).to eq([]) end end describe 'does not ignore archived dossiers' do let(:dossier) { create(:dossier, state: :en_construction, archived: true) } it { expect(searching(dossier.id.to_s)).to eq([dossier.id]) } end end describe '#matching_dossiers_for_user' do let(:user) { create(:user) } let(:another_user) { create(:user) } before { perform_enqueued_jobs(only: DossierIndexSearchTermsJob) } def searching(terms, user) = described_class.matching_dossiers_for_user(terms, user) context 'when the dossier is brouillon' do let(:procedure) { create(:procedure, types_de_champ_private: [{ type: :text }]) } let(:dossier) do create(:dossier, procedure:, state: :brouillon, user:).tap do |dossier| dossier.project_champs_private.first.update!(value: 'annotations') end end it do # searching its own dossier by id expect(searching(dossier.id.to_s, user)).to eq([dossier]) # searching another dossier by id expect(searching(dossier.id.to_s, another_user)).to eq([]) # annotations is unsearchable expect(searching('annotations', user)).to eq([]) end end context 'when the user is invited on the dossier' do let(:dossier) { create(:dossier) } before { create(:invite, dossier:, user:) } it { expect(searching(dossier.id.to_s, user)).to eq([dossier]) } end end end