123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- require 'rails_helper'
- RSpec.describe 'Elasticsearch', searchindex: true do
- let(:assets) { 'spec/fixtures/files/integration/elasticsearch' }
- let(:group) { create(:group) }
- let(:agent) { create(:agent, groups: [group]) }
- let(:customer) { create(:customer, organization: create(:organization)) }
- let(:ticket) { create(:ticket, owner: agent, customer: customer, group: group) }
- let(:article) { create(:ticket_article, :inbound_phone, ticket_id: ticket.id) }
- let(:attachment) do
- create(:store,
- object: 'Ticket::Article',
- o_id: article.id,
- data: Rails.root.join("#{assets}/es-normal.txt").binread,
- filename: 'es-normal.txt')
- end
- let(:customers) do
- organization = create(:organization)
- [
- create(:customer, organization: organization),
- create(:customer, organization: organization),
- create(:customer),
- ]
- end
- let(:tickets) do
- tickets = [
- create(:ticket, title: 'First test ticket', customer: customers[0], owner: agent, group: group),
- create(:ticket,
- title: 'Second test ticket',
- customer: customers[1],
- owner: agent,
- group: group,
- state: Ticket::State.lookup(name: 'open')),
- create(:ticket, title: 'Third test ticket', customer: customers[2]),
- ]
- tickets.each_index do |index|
- tickets[index].tag_add("Tag#{index + 1}", 1)
- end
- end
- let(:articles) do
- [
- create(:ticket_article, ticket_id: tickets[0].id).tap do |article|
- create(:store,
- object: 'Ticket::Article',
- o_id: article.id,
- data: Rails.root.join("#{assets}/es-normal.txt").binread,
- filename: 'es-normal.txt')
- create(:store,
- object: 'Ticket::Article',
- o_id: article.id,
- data: Rails.root.join("#{assets}/es-pdf1.pdf").binread,
- filename: 'es-pdf1.pdf')
- create(:store,
- object: 'Ticket::Article',
- o_id: article.id,
- data: Rails.root.join("#{assets}/es-box1.box").binread,
- filename: 'mail1.box')
- create(:store,
- object: 'Ticket::Article',
- o_id: article.id,
- data: Rails.root.join("#{assets}/es-too-big.txt").binread,
- filename: 'es-too-big.txt')
- end,
- create(:ticket_article,
- :inbound_email,
- ticket_id: tickets[1].id,
- subject: 'some subject2 / autobahn what else?',
- body: 'some other message <b>with s<u>t</u>rong text<b>',
- content_type: 'text/html'),
- create(:ticket_article,
- :inbound_email,
- ticket_id: tickets[2].id,
- body: 'some other message 3 / kindergarden what else?')
- ]
- end
- shared_examples 'user findable' do
- describe 'and findable' do
- it 'as agent' do
- result = User.search(current_user: agent, query: query)
- expect(result).to be_present
- end
- it 'not as customer' do
- result = User.search(current_user: customer, query: query)
- expect(result).not_to be_present
- end
- end
- end
- describe 'indexes agents' do
- let(:query) { agent.lastname }
- before do
- agent
- searchindex_model_reload([User])
- end
- it 'without sensible data' do
- lookup = agent.search_index_attribute_lookup
- expect(lookup).to include('id' => agent.id).and not_include('password')
- end
- include_examples 'user findable'
- end
- describe 'indexes customers' do
- let(:query) { customer.lastname }
- before do
- customer
- searchindex_model_reload([User])
- end
- it 'without sensible data' do
- lookup = customer.search_index_attribute_lookup
- expect(lookup).to include('id' => customer.id).and not_include('password')
- end
- it 'with organization' do
- lookup = customer.search_index_attribute_lookup
- expect(lookup['organization']['id']).to eq(customer.organization.id)
- end
- include_examples 'user findable'
- end
- describe 'indexes tickets' do
- context 'without sensible data' do
- before do
- ticket
- searchindex_model_reload([Ticket])
- end
- it 'without sensible data', :aggregate_failures do
- lookup = ticket.search_index_attribute_lookup
- expect(lookup['owner']).to not_include('password')
- expect(lookup['customer']).to not_include('password')
- end
- end
- context 'with article' do
- before do
- ticket && article && attachment
- searchindex_model_reload([Ticket])
- end
- it 'with article + attachment', :aggregate_failures do
- lookup = ticket.search_index_attribute_lookup
- expect(lookup['article'][0]['id']).to eq(article.id)
- expect(lookup['article'][0]['attachment'][0]['_name']).to match(attachment.filename)
- end
- end
- describe 'and findable' do
- before do
- ticket
- searchindex_model_reload([Ticket])
- end
- it 'as agent' do
- result = Ticket.search(current_user: agent, query: ticket.title)
- expect(result).to be_present
- end
- it 'as customer' do
- result = Ticket.search(current_user: customer, query: ticket.title)
- expect(result).to be_present
- end
- end
- describe 'and searchable', :aggregate_failures do
- context 'with agent' do
- before do
- ticket
- article
- attachment
- tickets
- articles
- searchindex_model_reload([Ticket])
- end
- it 'by tag' do
- result = Ticket.search(current_user: agent, query: 'Tag1')
- expect(result[0]['id']).to eq(tickets[0].id)
- expect(result.size).to eq(1)
- end
- it 'by customer' do
- result = Ticket.search(current_user: agent, query: tickets[0].customer.email)
- expect(result[0]['id']).to eq(tickets[0].id)
- expect(result.size).to eq(1)
- end
- it 'by article subject' do
- result = Ticket.search(current_user: agent, query: articles[0].subject)
- expect(result[0]['id']).to eq(tickets[0].id)
- expect(result.size).to eq(2)
- end
- it 'by article attachment content' do
- result = Ticket.search(current_user: agent, query: '"some normal text66"')
- expect(result[0]['id']).to eq(tickets[0].id)
- expect(result.size).to eq(2)
- end
- it 'not by big attachments' do
- result = Ticket.search(current_user: agent, query: '"some too big text88"')
- expect(result).not_to be_present
- end
- it 'by article html content' do
- result = Ticket.search(current_user: agent, query: 'strong')
- expect(result[0]['id']).to eq(tickets[1].id)
- expect(result.size).to eq(1)
- end
- it 'not without permission' do
- result = Ticket.search(current_user: agent, query: 'kindergarden')
- expect(result).not_to be_present
- end
- describe 'by query filter' do
- it 'tags' do
- result = Ticket.search(current_user: agent, query: 'tags:Tag2')
- expect(result[0]['id']).to eq(tickets[1].id)
- expect(result.size).to eq(1)
- end
- it 'state.name' do
- result = Ticket.search(current_user: agent, query: 'state.name:open')
- expect(result[0]['id']).to eq(tickets[1].id)
- expect(result.size).to eq(1)
- end
- it 'article.from' do
- result = Ticket.search(current_user: agent, query: "article.from:\"#{tickets[0].articles[0].from}\"")
- expect(result[0]['id']).to eq(tickets[1].id)
- expect(result.size).to eq(2)
- end
- end
- describe 'after modification', performs_jobs: true do
- before do
- tag_item = Tag::Item.lookup(name: 'Tag1')
- Tag::Item.rename(
- id: tag_item.id,
- name: 'Tag4711',
- updated_by_id: agent.id,
- )
- searchindex_model_reload([Ticket])
- end
- it 'tags' do
- result = Ticket.search(current_user: agent, query: 'tags:Tag4711')
- expect(result[0]['id']).to eq(tickets[0].id)
- expect(result.size).to eq(1)
- end
- end
- end
- context 'with customer' do
- before do
- tickets
- searchindex_model_reload([Ticket])
- end
- it 'by query OR clause' do
- result = Ticket.search(current_user: customers[0], query: 'First OR ticket')
- expect(result[0]['id']).to eq(tickets[1].id)
- expect(result[1]['id']).to eq(tickets[0].id)
- expect(result.size).to eq(2)
- end
- it 'not without permission by query OR clause' do
- result = Ticket.search(current_user: customers[2], query: 'First OR Second')
- expect(result).not_to be_present
- end
- end
- end
- end
- end
|