base_spec.rb 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Selector::Base, searchindex: true do
  4. let(:default_organization) { create(:organization) }
  5. let(:agent) { create(:agent, groups: [Group.first]) }
  6. let(:agent_owner) { create(:agent, groups: [Group.first], organization: default_organization) }
  7. let(:default_customer) { create(:customer, organization: default_organization) }
  8. let(:ticket_1) { create(:ticket, title: 'bli', group: Group.first, owner: agent_owner, customer: default_customer) }
  9. let(:ticket_2) { create(:ticket, title: 'bla', group: Group.first, owner: agent_owner, customer: default_customer) }
  10. let(:ticket_3) { create(:ticket, title: 'blub', group: Group.first, owner: agent_owner, customer: default_customer) }
  11. before do
  12. Ticket.destroy_all
  13. ticket_1 && ticket_2 && ticket_3
  14. searchindex_model_reload([Ticket])
  15. end
  16. it 'does support AND conditions', :aggregate_failures do
  17. condition = {
  18. operator: 'AND',
  19. conditions: [
  20. {
  21. name: 'ticket.title',
  22. operator: 'contains',
  23. value: 'b',
  24. },
  25. {
  26. name: 'ticket.title',
  27. operator: 'contains',
  28. value: 'l',
  29. },
  30. {
  31. name: 'ticket.title',
  32. operator: 'contains',
  33. value: 'b',
  34. },
  35. ]
  36. }
  37. count, = Ticket.selectors(condition, { current_user: agent })
  38. expect(count).to eq(3)
  39. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  40. expect(result[:count]).to eq(3)
  41. end
  42. it 'does support NOT conditions', :aggregate_failures do
  43. condition = {
  44. operator: 'NOT',
  45. conditions: [
  46. {
  47. name: 'ticket.title',
  48. operator: 'contains',
  49. value: 'b',
  50. },
  51. {
  52. name: 'ticket.title',
  53. operator: 'contains',
  54. value: 'l',
  55. },
  56. {
  57. name: 'ticket.title',
  58. operator: 'contains',
  59. value: 'b',
  60. },
  61. ]
  62. }
  63. count, = Ticket.selectors(condition, { current_user: agent })
  64. expect(count).to eq(0)
  65. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  66. expect(result[:count]).to eq(0)
  67. end
  68. it 'does support OR conditions', :aggregate_failures do
  69. condition = {
  70. operator: 'OR',
  71. conditions: [
  72. {
  73. name: 'ticket.title',
  74. operator: 'is',
  75. value: 'bli',
  76. },
  77. {
  78. name: 'ticket.title',
  79. operator: 'is',
  80. value: 'bla',
  81. },
  82. {
  83. name: 'ticket.title',
  84. operator: 'is',
  85. value: 'blub',
  86. },
  87. ]
  88. }
  89. count, = Ticket.selectors(condition, { current_user: agent })
  90. expect(count).to eq(3)
  91. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  92. expect(result[:count]).to eq(3)
  93. end
  94. it 'does support OR conditions (one missing)', :aggregate_failures do
  95. condition = {
  96. operator: 'OR',
  97. conditions: [
  98. {
  99. name: 'ticket.title',
  100. operator: 'is',
  101. value: 'xxx',
  102. },
  103. {
  104. name: 'ticket.title',
  105. operator: 'is',
  106. value: 'bla',
  107. },
  108. {
  109. name: 'ticket.title',
  110. operator: 'is',
  111. value: 'blub',
  112. },
  113. ]
  114. }
  115. count, = Ticket.selectors(condition, { current_user: agent })
  116. expect(count).to eq(2)
  117. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  118. expect(result[:count]).to eq(2)
  119. end
  120. it 'does support OR conditions (all missing)', :aggregate_failures do
  121. condition = {
  122. operator: 'AND',
  123. conditions: [
  124. {
  125. name: 'ticket.title',
  126. operator: 'is',
  127. value: 'bli',
  128. },
  129. {
  130. name: 'ticket.title',
  131. operator: 'is',
  132. value: 'bla',
  133. },
  134. {
  135. name: 'ticket.title',
  136. operator: 'is',
  137. value: 'blub',
  138. },
  139. ]
  140. }
  141. count, = Ticket.selectors(condition, { current_user: agent })
  142. expect(count).to eq(0)
  143. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  144. expect(result[:count]).to eq(0)
  145. end
  146. it 'does support sub level conditions', :aggregate_failures do
  147. condition = {
  148. operator: 'OR',
  149. conditions: [
  150. {
  151. name: 'ticket.title',
  152. operator: 'is',
  153. value: 'bli',
  154. },
  155. {
  156. operator: 'OR',
  157. conditions: [
  158. {
  159. name: 'ticket.title',
  160. operator: 'is',
  161. value: 'bla',
  162. },
  163. {
  164. name: 'ticket.title',
  165. operator: 'is',
  166. value: 'blub',
  167. },
  168. ],
  169. }
  170. ]
  171. }
  172. count, = Ticket.selectors(condition, { current_user: agent })
  173. expect(count).to eq(3)
  174. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  175. expect(result[:count]).to eq(3)
  176. end
  177. it 'does support sub level conditions (one missing)', :aggregate_failures do
  178. condition = {
  179. operator: 'OR',
  180. conditions: [
  181. {
  182. name: 'ticket.title',
  183. operator: 'is',
  184. value: 'bli',
  185. },
  186. {
  187. operator: 'OR',
  188. conditions: [
  189. {
  190. name: 'ticket.title',
  191. operator: 'is',
  192. value: 'xxx',
  193. },
  194. {
  195. name: 'ticket.title',
  196. operator: 'is',
  197. value: 'blub',
  198. },
  199. ],
  200. }
  201. ]
  202. }
  203. count, = Ticket.selectors(condition, { current_user: agent })
  204. expect(count).to eq(2)
  205. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  206. expect(result[:count]).to eq(2)
  207. end
  208. it 'does support sub level conditions (all missing)', :aggregate_failures do
  209. condition = {
  210. operator: 'AND',
  211. conditions: [
  212. {
  213. name: 'ticket.title',
  214. operator: 'is',
  215. value: 'bli',
  216. },
  217. {
  218. operator: 'AND',
  219. conditions: [
  220. {
  221. name: 'ticket.title',
  222. operator: 'is',
  223. value: 'bla',
  224. },
  225. {
  226. name: 'ticket.title',
  227. operator: 'is',
  228. value: 'blub',
  229. },
  230. ],
  231. }
  232. ]
  233. }
  234. count, = Ticket.selectors(condition, { current_user: agent })
  235. expect(count).to eq(0)
  236. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  237. expect(result[:count]).to eq(0)
  238. end
  239. it 'does return all 3 results on empty condition', :aggregate_failures do
  240. condition = {
  241. operator: 'AND',
  242. conditions: []
  243. }
  244. count, = Ticket.selectors(condition, { current_user: agent })
  245. expect(count).to eq(3)
  246. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  247. expect(result[:count]).to eq(3)
  248. end
  249. it 'does return all 3 results on empty sub condition', :aggregate_failures do
  250. condition = {
  251. operator: 'AND',
  252. conditions: [
  253. {
  254. name: 'ticket.title',
  255. operator: 'contains',
  256. value: 'b',
  257. },
  258. {
  259. name: 'ticket.title',
  260. operator: 'contains',
  261. value: 'l',
  262. },
  263. {
  264. name: 'ticket.title',
  265. operator: 'contains',
  266. value: 'b',
  267. },
  268. {
  269. operator: 'AND',
  270. conditions: [
  271. ],
  272. }
  273. ]
  274. }
  275. count, = Ticket.selectors(condition, { current_user: agent })
  276. expect(count).to eq(3)
  277. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  278. expect(result[:count]).to eq(3)
  279. end
  280. it 'does return all 3 results on empty sub sub condition', :aggregate_failures do
  281. condition = {
  282. operator: 'AND',
  283. conditions: [
  284. {
  285. name: 'ticket.title',
  286. operator: 'contains',
  287. value: 'b',
  288. },
  289. {
  290. name: 'ticket.title',
  291. operator: 'contains',
  292. value: 'l',
  293. },
  294. {
  295. name: 'ticket.title',
  296. operator: 'contains',
  297. value: 'b',
  298. },
  299. {
  300. operator: 'AND',
  301. conditions: [
  302. {
  303. operator: 'AND',
  304. conditions: [
  305. ],
  306. }
  307. ],
  308. }
  309. ]
  310. }
  311. count, = Ticket.selectors(condition, { current_user: agent })
  312. expect(count).to eq(3)
  313. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  314. expect(result[:count]).to eq(3)
  315. end
  316. it 'does support owner_id is not_set pre_condition', :aggregate_failures do
  317. condition = {
  318. operator: 'AND',
  319. conditions: [
  320. {
  321. pre_condition: 'not_set',
  322. name: 'ticket.owner_id',
  323. operator: 'is',
  324. value: [],
  325. },
  326. ]
  327. }
  328. count, = Ticket.selectors(condition, { current_user: agent })
  329. expect(count).to eq(0)
  330. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  331. expect(result[:count]).to eq(0)
  332. end
  333. it 'does support owner_id is not not_set pre_condition', :aggregate_failures do
  334. condition = {
  335. operator: 'AND',
  336. conditions: [
  337. {
  338. pre_condition: 'not_set',
  339. name: 'ticket.owner_id',
  340. operator: 'is not',
  341. value: [],
  342. },
  343. ]
  344. }
  345. count, = Ticket.selectors(condition, { current_user: agent })
  346. expect(count).to eq(3)
  347. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  348. expect(result[:count]).to eq(3)
  349. end
  350. it 'does support owner is current_user.id pre_condition', :aggregate_failures do
  351. condition = {
  352. operator: 'AND',
  353. conditions: [
  354. {
  355. pre_condition: 'current_user.id',
  356. name: 'ticket.owner_id',
  357. operator: 'is',
  358. value: [],
  359. },
  360. ]
  361. }
  362. count, = Ticket.selectors(condition, { current_user: agent_owner })
  363. expect(count).to eq(3)
  364. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent_owner })
  365. expect(result[:count]).to eq(3)
  366. end
  367. it 'does support owner is current_user.id pre_condition but user has none', :aggregate_failures do
  368. condition = {
  369. operator: 'AND',
  370. conditions: [
  371. {
  372. pre_condition: 'current_user.id',
  373. name: 'ticket.owner_id',
  374. operator: 'is',
  375. value: [],
  376. },
  377. ]
  378. }
  379. count, = Ticket.selectors(condition, { current_user: agent })
  380. expect(count).to eq(0)
  381. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  382. expect(result[:count]).to eq(0)
  383. end
  384. it 'does support owner is current_user.organization_id pre_condition', :aggregate_failures do
  385. condition = {
  386. operator: 'AND',
  387. conditions: [
  388. {
  389. pre_condition: 'current_user.organization_id',
  390. name: 'ticket.organization_id',
  391. operator: 'is',
  392. value: [],
  393. },
  394. ]
  395. }
  396. count, = Ticket.selectors(condition, { current_user: agent_owner })
  397. expect(count).to eq(3)
  398. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent_owner })
  399. expect(result[:count]).to eq(3)
  400. end
  401. it 'does support owner is current_user.organization_id pre_condition but user has none', :aggregate_failures do
  402. condition = {
  403. operator: 'AND',
  404. conditions: [
  405. {
  406. pre_condition: 'current_user.organization_id',
  407. name: 'ticket.organization_id',
  408. operator: 'is',
  409. value: [],
  410. },
  411. ]
  412. }
  413. count, = Ticket.selectors(condition, { current_user: agent })
  414. expect(count).to eq(0)
  415. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  416. expect(result[:count]).to eq(0)
  417. end
  418. describe 'Report profile terminates with error if today is used as timestamp for condition #4901' do
  419. before do
  420. ticket_1.update(created_at: 1.day.ago)
  421. searchindex_model_reload([Ticket])
  422. end
  423. it 'does support today operator', :aggregate_failures do
  424. condition = {
  425. operator: 'AND',
  426. conditions: [
  427. {
  428. name: 'ticket.created_at',
  429. operator: 'today',
  430. },
  431. ]
  432. }
  433. count, = Ticket.selectors(condition, { current_user: agent })
  434. expect(count).to eq(2)
  435. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  436. expect(result[:count]).to eq(2)
  437. end
  438. end
  439. describe 'Trigger do not allow "Multi-Tree-Select" Fields on Organization and User Level as If Condition #4504', db_strategy: :reset do
  440. let(:field_name) { SecureRandom.uuid }
  441. let(:organization) { create(:organization, field_name => ['Incident', 'Incident::Hardware']) }
  442. let(:customer) { create(:customer, organization: organization, field_name => ['Incident', 'Incident::Hardware']) }
  443. let(:ticket) { create(:ticket, title: 'bli', group: Group.first, customer: customer, field_name => ['Incident', 'Incident::Hardware']) }
  444. def check_condition(attribute)
  445. condition = {
  446. operator: 'AND',
  447. conditions: [
  448. {
  449. name: attribute.to_s,
  450. operator: 'contains all',
  451. value: ['Incident', 'Incident::Hardware'],
  452. }
  453. ]
  454. }
  455. count, = Ticket.selectors(condition, { current_user: agent })
  456. expect(count).to eq(1)
  457. count, = Ticket.selectors(condition, { current_user: agent })
  458. expect(count).to eq(1)
  459. end
  460. before do
  461. create(:object_manager_attribute_multi_tree_select, object_name: 'Ticket', name: field_name)
  462. create(:object_manager_attribute_multi_tree_select, object_name: 'User', name: field_name)
  463. create(:object_manager_attribute_multi_tree_select, object_name: 'Organization', name: field_name)
  464. ObjectManager::Attribute.migration_execute
  465. ticket
  466. searchindex_model_reload([Ticket, User, Organization])
  467. end
  468. it 'does support contains one for all objects' do # rubocop:disable RSpec/NoExpectationExample
  469. check_condition("ticket.#{field_name}")
  470. check_condition("customer.#{field_name}")
  471. check_condition("organization.#{field_name}")
  472. end
  473. end
  474. describe 'Reporting profiles do not work with multi tree select #4546' do
  475. context 'when value is a string' do
  476. before do
  477. create(:tag, tag_item: create(:'tag/item', name: 'AAA'), o: ticket_1)
  478. create(:tag, tag_item: create(:'tag/item', name: 'BBB'), o: ticket_1)
  479. searchindex_model_reload([Ticket])
  480. end
  481. it 'does return ticket by contains all string value', :aggregate_failures do
  482. condition = {
  483. operator: 'AND',
  484. conditions: [
  485. {
  486. name: 'ticket.tags',
  487. operator: 'contains all',
  488. value: 'AAA, BBB',
  489. }
  490. ]
  491. }
  492. count, = Ticket.selectors(condition, { current_user: agent })
  493. expect(count).to eq(1)
  494. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  495. expect(result[:count]).to eq(1)
  496. end
  497. end
  498. context 'when value is an array', db_strategy: :reset do
  499. let(:field_name) { SecureRandom.uuid }
  500. before do
  501. create(:object_manager_attribute_multi_tree_select, name: field_name)
  502. ObjectManager::Attribute.migration_execute
  503. ticket_1.reload.update(field_name => ['Incident', 'Incident::Hardware'])
  504. searchindex_model_reload([Ticket])
  505. end
  506. it 'does return ticket by contains all array value', :aggregate_failures do
  507. condition = {
  508. operator: 'AND',
  509. conditions: [
  510. {
  511. name: "ticket.#{field_name}",
  512. operator: 'contains all',
  513. value: ['Incident', 'Incident::Hardware'],
  514. }
  515. ]
  516. }
  517. count, = Ticket.selectors(condition, { current_user: agent })
  518. expect(count).to eq(1)
  519. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  520. expect(result[:count]).to eq(1)
  521. end
  522. end
  523. end
  524. describe 'Report profiles: Problem with some conditions (starts with, ends with, is any, is none) #4798' do
  525. context 'when operator is any of' do
  526. it 'does match', :aggregate_failures do
  527. condition = {
  528. operator: 'OR',
  529. conditions: [
  530. {
  531. name: 'ticket.title',
  532. operator: 'is any of',
  533. value: %w[bli bla],
  534. },
  535. {
  536. name: 'ticket.title',
  537. operator: 'is any of',
  538. value: ['blub'],
  539. },
  540. ]
  541. }
  542. count, = Ticket.selectors(condition, { current_user: agent })
  543. expect(count).to eq(3)
  544. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  545. expect(result[:count]).to eq(3)
  546. end
  547. it 'does not match', :aggregate_failures do
  548. condition = {
  549. operator: 'OR',
  550. conditions: [
  551. {
  552. name: 'ticket.title',
  553. operator: 'is any of',
  554. value: %w[blix blax],
  555. },
  556. {
  557. name: 'ticket.title',
  558. operator: 'is any of',
  559. value: ['blubx'],
  560. },
  561. ]
  562. }
  563. count, = Ticket.selectors(condition, { current_user: agent })
  564. expect(count).to eq(0)
  565. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  566. expect(result[:count]).to eq(0)
  567. end
  568. end
  569. context 'when operator is none of' do
  570. it 'does match', :aggregate_failures do
  571. condition = {
  572. operator: 'OR',
  573. conditions: [
  574. {
  575. name: 'ticket.title',
  576. operator: 'is none of',
  577. value: %w[blix blax],
  578. },
  579. {
  580. name: 'ticket.title',
  581. operator: 'is none of',
  582. value: ['blubx'],
  583. },
  584. ]
  585. }
  586. count, = Ticket.selectors(condition, { current_user: agent })
  587. expect(count).to eq(3)
  588. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  589. expect(result[:count]).to eq(3)
  590. end
  591. it 'does not match', :aggregate_failures do
  592. condition = {
  593. operator: 'AND',
  594. conditions: [
  595. {
  596. name: 'ticket.title',
  597. operator: 'is none of',
  598. value: %w[bli bla],
  599. },
  600. {
  601. name: 'ticket.title',
  602. operator: 'is none of',
  603. value: ['blub'],
  604. },
  605. ]
  606. }
  607. count, = Ticket.selectors(condition, { current_user: agent })
  608. expect(count).to eq(0)
  609. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  610. expect(result[:count]).to eq(0)
  611. end
  612. end
  613. context 'when operator starts with one of' do
  614. it 'does match', :aggregate_failures do
  615. condition = {
  616. operator: 'AND',
  617. conditions: [
  618. {
  619. name: 'ticket.title',
  620. operator: 'starts with one of',
  621. value: ['bl'],
  622. },
  623. ]
  624. }
  625. count, = Ticket.selectors(condition, { current_user: agent })
  626. expect(count).to eq(3)
  627. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  628. expect(result[:count]).to eq(3)
  629. end
  630. it 'does not match', :aggregate_failures do
  631. condition = {
  632. operator: 'AND',
  633. conditions: [
  634. {
  635. name: 'ticket.title',
  636. operator: 'starts with one of',
  637. value: ['aaa'],
  638. },
  639. ]
  640. }
  641. count, = Ticket.selectors(condition, { current_user: agent })
  642. expect(count).to eq(0)
  643. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  644. expect(result[:count]).to eq(0)
  645. end
  646. end
  647. context 'when operator ends with one of' do
  648. it 'does match', :aggregate_failures do
  649. condition = {
  650. operator: 'OR',
  651. conditions: [
  652. {
  653. name: 'ticket.title',
  654. operator: 'ends with one of',
  655. value: %w[li la],
  656. },
  657. {
  658. name: 'ticket.title',
  659. operator: 'ends with one of',
  660. value: ['ub'],
  661. },
  662. ]
  663. }
  664. count, = Ticket.selectors(condition, { current_user: agent })
  665. expect(count).to eq(3)
  666. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  667. expect(result[:count]).to eq(3)
  668. end
  669. it 'does not match', :aggregate_failures do
  670. condition = {
  671. operator: 'AND',
  672. conditions: [
  673. {
  674. name: 'ticket.title',
  675. operator: 'ends with one of',
  676. value: ['ubx'],
  677. },
  678. ]
  679. }
  680. count, = Ticket.selectors(condition, { current_user: agent })
  681. expect(count).to eq(0)
  682. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  683. expect(result[:count]).to eq(0)
  684. end
  685. end
  686. end
  687. describe 'Tags' do
  688. let(:ta) { create(:'tag/item', name: 'a') }
  689. let(:tb) { create(:'tag/item', name: 'b') }
  690. let(:tc) { create(:'tag/item', name: 'c') }
  691. let(:td) { create(:'tag/item', name: 'd') }
  692. let(:ticket_a) do
  693. create(:ticket, group: Group.first).tap do |ticket|
  694. create(:tag, o: ticket, tag_item: ta)
  695. end
  696. end
  697. let(:ticket_a_b) do
  698. create(:ticket, group: Group.first).tap do |ticket|
  699. create(:tag, o: ticket, tag_item: ta)
  700. create(:tag, o: ticket, tag_item: tb)
  701. end
  702. end
  703. let(:ticket_none) { create(:ticket, group: Group.first) }
  704. before do
  705. Ticket.destroy_all
  706. ta && tb && tc && td
  707. ticket_a && ticket_a_b && ticket_none
  708. searchindex_model_reload([Ticket])
  709. end
  710. describe 'contains all' do
  711. it 'checks tags a = 2', :aggregate_failures do
  712. condition = {
  713. operator: 'AND',
  714. conditions: [
  715. {
  716. name: 'ticket.tags',
  717. operator: 'contains all',
  718. value: 'a',
  719. },
  720. ]
  721. }
  722. count, = Ticket.selectors(condition, { current_user: agent })
  723. expect(count).to eq(2)
  724. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  725. expect(result[:count]).to eq(2)
  726. end
  727. it 'checks tags a, b = 1', :aggregate_failures do
  728. condition = {
  729. operator: 'AND',
  730. conditions: [
  731. {
  732. name: 'ticket.tags',
  733. operator: 'contains all',
  734. value: 'a,b',
  735. },
  736. ]
  737. }
  738. count, = Ticket.selectors(condition, { current_user: agent })
  739. expect(count).to eq(1)
  740. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  741. expect(result[:count]).to eq(1)
  742. end
  743. it 'checks tags a, c = 0', :aggregate_failures do
  744. condition = {
  745. operator: 'AND',
  746. conditions: [
  747. {
  748. name: 'ticket.tags',
  749. operator: 'contains all',
  750. value: 'a,c',
  751. },
  752. ]
  753. }
  754. count, = Ticket.selectors(condition, { current_user: agent })
  755. expect(count).to eq(0)
  756. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  757. expect(result[:count]).to eq(0)
  758. end
  759. it 'checks tags a, b, c = 0', :aggregate_failures do
  760. condition = {
  761. operator: 'AND',
  762. conditions: [
  763. {
  764. name: 'ticket.tags',
  765. operator: 'contains all',
  766. value: 'a,b,c',
  767. },
  768. ]
  769. }
  770. count, = Ticket.selectors(condition, { current_user: agent })
  771. expect(count).to eq(0)
  772. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  773. expect(result[:count]).to eq(0)
  774. end
  775. it 'checks tags c, d = 0', :aggregate_failures do
  776. condition = {
  777. operator: 'AND',
  778. conditions: [
  779. {
  780. name: 'ticket.tags',
  781. operator: 'contains all',
  782. value: 'c,d',
  783. },
  784. ]
  785. }
  786. count, = Ticket.selectors(condition, { current_user: agent })
  787. expect(count).to eq(0)
  788. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  789. expect(result[:count]).to eq(0)
  790. end
  791. it 'checks tags d = 0', :aggregate_failures do
  792. condition = {
  793. operator: 'AND',
  794. conditions: [
  795. {
  796. name: 'ticket.tags',
  797. operator: 'contains all',
  798. value: 'd',
  799. },
  800. ]
  801. }
  802. count, = Ticket.selectors(condition, { current_user: agent })
  803. expect(count).to eq(0)
  804. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  805. expect(result[:count]).to eq(0)
  806. end
  807. end
  808. describe 'contains one' do
  809. it 'checks tags a = 2', :aggregate_failures do
  810. condition = {
  811. operator: 'AND',
  812. conditions: [
  813. {
  814. name: 'ticket.tags',
  815. operator: 'contains one',
  816. value: 'a',
  817. },
  818. ]
  819. }
  820. count, = Ticket.selectors(condition, { current_user: agent })
  821. expect(count).to eq(2)
  822. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  823. expect(result[:count]).to eq(2)
  824. end
  825. it 'checks tags a, b = 2', :aggregate_failures do
  826. condition = {
  827. operator: 'AND',
  828. conditions: [
  829. {
  830. name: 'ticket.tags',
  831. operator: 'contains one',
  832. value: 'a,b',
  833. },
  834. ]
  835. }
  836. count, = Ticket.selectors(condition, { current_user: agent })
  837. expect(count).to eq(2)
  838. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  839. expect(result[:count]).to eq(2)
  840. end
  841. it 'checks tags a, c = 2', :aggregate_failures do
  842. condition = {
  843. operator: 'AND',
  844. conditions: [
  845. {
  846. name: 'ticket.tags',
  847. operator: 'contains one',
  848. value: 'a,c',
  849. },
  850. ]
  851. }
  852. count, = Ticket.selectors(condition, { current_user: agent })
  853. expect(count).to eq(2)
  854. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  855. expect(result[:count]).to eq(2)
  856. end
  857. it 'checks tags a, b, c = 2', :aggregate_failures do
  858. condition = {
  859. operator: 'AND',
  860. conditions: [
  861. {
  862. name: 'ticket.tags',
  863. operator: 'contains one',
  864. value: 'a,b,c',
  865. },
  866. ]
  867. }
  868. count, = Ticket.selectors(condition, { current_user: agent })
  869. expect(count).to eq(2)
  870. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  871. expect(result[:count]).to eq(2)
  872. end
  873. it 'checks tags c, d = 0', :aggregate_failures do
  874. condition = {
  875. operator: 'AND',
  876. conditions: [
  877. {
  878. name: 'ticket.tags',
  879. operator: 'contains one',
  880. value: 'c,d',
  881. },
  882. ]
  883. }
  884. count, = Ticket.selectors(condition, { current_user: agent })
  885. expect(count).to eq(0)
  886. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  887. expect(result[:count]).to eq(0)
  888. end
  889. it 'checks tags d = 0', :aggregate_failures do
  890. condition = {
  891. operator: 'AND',
  892. conditions: [
  893. {
  894. name: 'ticket.tags',
  895. operator: 'contains one',
  896. value: 'd',
  897. },
  898. ]
  899. }
  900. count, = Ticket.selectors(condition, { current_user: agent })
  901. expect(count).to eq(0)
  902. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  903. expect(result[:count]).to eq(0)
  904. end
  905. end
  906. describe 'contains all not' do
  907. it 'checks tags a = 1', :aggregate_failures do
  908. condition = {
  909. operator: 'AND',
  910. conditions: [
  911. {
  912. name: 'ticket.tags',
  913. operator: 'contains all not',
  914. value: 'a',
  915. },
  916. ]
  917. }
  918. count, = Ticket.selectors(condition, { current_user: agent })
  919. expect(count).to eq(1)
  920. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  921. expect(result[:count]).to eq(1)
  922. end
  923. it 'checks tags a, b = 2', :aggregate_failures do
  924. condition = {
  925. operator: 'AND',
  926. conditions: [
  927. {
  928. name: 'ticket.tags',
  929. operator: 'contains all not',
  930. value: 'a,b',
  931. },
  932. ]
  933. }
  934. count, = Ticket.selectors(condition, { current_user: agent })
  935. expect(count).to eq(2)
  936. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  937. expect(result[:count]).to eq(2)
  938. end
  939. it 'checks tags a, c = 3', :aggregate_failures do
  940. condition = {
  941. operator: 'AND',
  942. conditions: [
  943. {
  944. name: 'ticket.tags',
  945. operator: 'contains all not',
  946. value: 'a,c',
  947. },
  948. ]
  949. }
  950. count, = Ticket.selectors(condition, { current_user: agent })
  951. expect(count).to eq(3)
  952. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  953. expect(result[:count]).to eq(3)
  954. end
  955. it 'checks tags a, b, c = 3', :aggregate_failures do
  956. condition = {
  957. operator: 'AND',
  958. conditions: [
  959. {
  960. name: 'ticket.tags',
  961. operator: 'contains all not',
  962. value: 'a,b,c',
  963. },
  964. ]
  965. }
  966. count, = Ticket.selectors(condition, { current_user: agent })
  967. expect(count).to eq(3)
  968. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  969. expect(result[:count]).to eq(3)
  970. end
  971. it 'checks tags c, d = 3', :aggregate_failures do
  972. condition = {
  973. operator: 'AND',
  974. conditions: [
  975. {
  976. name: 'ticket.tags',
  977. operator: 'contains all not',
  978. value: 'c,d',
  979. },
  980. ]
  981. }
  982. count, = Ticket.selectors(condition, { current_user: agent })
  983. expect(count).to eq(3)
  984. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  985. expect(result[:count]).to eq(3)
  986. end
  987. it 'checks tags d = 3', :aggregate_failures do
  988. condition = {
  989. operator: 'AND',
  990. conditions: [
  991. {
  992. name: 'ticket.tags',
  993. operator: 'contains all not',
  994. value: 'd',
  995. },
  996. ]
  997. }
  998. count, = Ticket.selectors(condition, { current_user: agent })
  999. expect(count).to eq(3)
  1000. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  1001. expect(result[:count]).to eq(3)
  1002. end
  1003. end
  1004. describe 'contains one not' do
  1005. it 'checks tags a = 1', :aggregate_failures do
  1006. condition = {
  1007. operator: 'AND',
  1008. conditions: [
  1009. {
  1010. name: 'ticket.tags',
  1011. operator: 'contains one not',
  1012. value: 'a',
  1013. },
  1014. ]
  1015. }
  1016. count, = Ticket.selectors(condition, { current_user: agent })
  1017. expect(count).to eq(1)
  1018. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  1019. expect(result[:count]).to eq(1)
  1020. end
  1021. it 'checks tags a, b = 1', :aggregate_failures do
  1022. condition = {
  1023. operator: 'AND',
  1024. conditions: [
  1025. {
  1026. name: 'ticket.tags',
  1027. operator: 'contains one not',
  1028. value: 'a,b',
  1029. },
  1030. ]
  1031. }
  1032. count, = Ticket.selectors(condition, { current_user: agent })
  1033. expect(count).to eq(1)
  1034. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  1035. expect(result[:count]).to eq(1)
  1036. end
  1037. it 'checks tags a, c = 1', :aggregate_failures do
  1038. condition = {
  1039. operator: 'AND',
  1040. conditions: [
  1041. {
  1042. name: 'ticket.tags',
  1043. operator: 'contains one not',
  1044. value: 'a,c',
  1045. },
  1046. ]
  1047. }
  1048. count, = Ticket.selectors(condition, { current_user: agent })
  1049. expect(count).to eq(1)
  1050. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  1051. expect(result[:count]).to eq(1)
  1052. end
  1053. it 'checks tags a, b, c = 1', :aggregate_failures do
  1054. condition = {
  1055. operator: 'AND',
  1056. conditions: [
  1057. {
  1058. name: 'ticket.tags',
  1059. operator: 'contains one not',
  1060. value: 'a,b,c',
  1061. },
  1062. ]
  1063. }
  1064. count, = Ticket.selectors(condition, { current_user: agent })
  1065. expect(count).to eq(1)
  1066. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  1067. expect(result[:count]).to eq(1)
  1068. end
  1069. it 'checks tags c, d = 3', :aggregate_failures do
  1070. condition = {
  1071. operator: 'AND',
  1072. conditions: [
  1073. {
  1074. name: 'ticket.tags',
  1075. operator: 'contains one not',
  1076. value: 'c,d',
  1077. },
  1078. ]
  1079. }
  1080. count, = Ticket.selectors(condition, { current_user: agent })
  1081. expect(count).to eq(3)
  1082. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  1083. expect(result[:count]).to eq(3)
  1084. end
  1085. it 'checks tags d = 3', :aggregate_failures do
  1086. condition = {
  1087. operator: 'AND',
  1088. conditions: [
  1089. {
  1090. name: 'ticket.tags',
  1091. operator: 'contains one not',
  1092. value: 'd',
  1093. },
  1094. ]
  1095. }
  1096. count, = Ticket.selectors(condition, { current_user: agent })
  1097. expect(count).to eq(3)
  1098. result = SearchIndexBackend.selectors('Ticket', condition, { current_user: agent })
  1099. expect(result[:count]).to eq(3)
  1100. end
  1101. end
  1102. end
  1103. end