online_notification_spec.rb 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. require 'models/application_model_examples'
  4. RSpec.describe OnlineNotification, type: :model do
  5. subject(:online_notification) { create(:online_notification, o: ticket) }
  6. let(:ticket) { create(:ticket) }
  7. it_behaves_like 'ApplicationModel', can_param: { sample_data_attribute: :seen }
  8. describe '#related_object' do
  9. it 'returns ticket' do
  10. expect(online_notification.related_object).to eq ticket
  11. end
  12. end
  13. describe '.add' do
  14. describe 'validations' do
  15. describe 'referenced object' do
  16. it 'raises RuntimeError for invalid object name' do
  17. expect do
  18. described_class.add(
  19. type: 'create',
  20. object: 'TicketNotExisting',
  21. o_id: 123,
  22. seen: false,
  23. user_id: create(:agent).id,
  24. created_by_id: 1,
  25. updated_by_id: 1,
  26. created_at: 10.months.ago,
  27. updated_at: 10.months.ago,
  28. )
  29. end.to raise_error(RuntimeError)
  30. end
  31. it 'raises RecordNotFound if object does not exist' do
  32. expect do
  33. described_class.add(
  34. type: 'create',
  35. object: 'Ticket',
  36. o_id: 123,
  37. seen: false,
  38. user_id: create(:agent).id,
  39. created_by_id: 1,
  40. updated_by_id: 1,
  41. created_at: 10.months.ago,
  42. updated_at: 10.months.ago,
  43. )
  44. end.to raise_error(ActiveRecord::RecordNotFound)
  45. end
  46. end
  47. end
  48. end
  49. describe '.list' do
  50. let(:user) { create(:agent, groups: [group]) }
  51. let(:another_user) { create(:agent, groups: [group]) }
  52. let(:group) { create(:group) }
  53. let(:ticket) { create(:ticket, group: group) }
  54. let(:another_ticket) { create(:ticket, group: group) }
  55. let(:notification_1) { create(:online_notification, o: ticket, user: user) }
  56. let(:notification_2) { create(:online_notification, o: ticket, user: another_user) }
  57. let(:notification_3) { create(:online_notification, o: another_ticket, user: user) }
  58. before do
  59. notification_1 && notification_2 && notification_3
  60. end
  61. it 'returns notifications for a given user' do
  62. expect(described_class.list(user))
  63. .to contain_exactly(notification_1, notification_3)
  64. end
  65. context 'when user looses access to one of the referenced tickets' do
  66. before do
  67. another_ticket.update! group: create(:group)
  68. end
  69. it 'with ensure_access flag it returns notifications given user has access to' do
  70. expect(described_class.list(user, access: 'full'))
  71. .to contain_exactly(notification_1)
  72. end
  73. it 'without ensure_access flag it returns all notifications given user has' do
  74. expect(described_class.list(user, access: 'ignore'))
  75. .to contain_exactly(notification_1, notification_3)
  76. end
  77. end
  78. end
  79. describe 'notification creation', performs_jobs: true do
  80. let(:group) { create(:group) }
  81. let(:agent1) { create(:agent, groups: [group]) }
  82. let(:agent2) { create(:agent, groups: [group]) }
  83. let(:agent3) { create(:agent) }
  84. let(:customer) { create(:customer) }
  85. let(:system) { User.lookup(login: '-') }
  86. let(:ticket) do
  87. create(:ticket,
  88. group: group,
  89. customer: customer,
  90. owner: ticket_owner,
  91. state_name: state_name,
  92. updated_by: ticket_author,
  93. created_by: ticket_author)
  94. end
  95. let(:first_article) do
  96. create(:ticket_article,
  97. ticket: ticket,
  98. type_name: 'phone',
  99. sender_name: 'Customer',
  100. from: 'Unit Test <unittest@example.com>',
  101. body: 'Unit Test 123',
  102. internal: false,
  103. updated_by: article_author,
  104. created_by: article_author)
  105. end
  106. def notifications_scope(type_name)
  107. described_class.where(
  108. object_lookup_id: ObjectLookup.by_name('Ticket'),
  109. type_lookup_id: TypeLookup.by_name(type_name),
  110. o_id: ticket.id
  111. )
  112. end
  113. around do |example|
  114. ApplicationHandleInfo.use('application_server') do
  115. example.run
  116. end
  117. end
  118. before do
  119. agent1 && agent2 && agent3 && customer
  120. first_article
  121. perform_enqueued_jobs commit_transaction: true
  122. end
  123. shared_examples 'destroyable notifications' do
  124. let(:destroyable_ticket) { ticket }
  125. it 'removes all notifications when destroying a ticket' do
  126. destroyable_ticket.destroy
  127. expect(described_class.list_by_object('Ticket', destroyable_ticket.id))
  128. .to be_blank
  129. end
  130. end
  131. context 'when closed ticket owner is system' do
  132. let(:ticket_owner) { system }
  133. let(:ticket_author) { agent1 }
  134. let(:article_author) { agent1 }
  135. let(:state_name) { 'closed' }
  136. it 'adds already seen create notification for the other agent' do
  137. expect(notifications_scope('create'))
  138. .to contain_exactly(
  139. have_attributes(user: agent2, created_by: agent1, seen: true)
  140. )
  141. end
  142. it_behaves_like 'destroyable notifications'
  143. context 'when customer updates a closed ticket' do
  144. before do
  145. ticket.update!(
  146. state_id: Ticket::State.lookup(name: 'open').id,
  147. priority_id: Ticket::Priority.lookup(name: '1 low').id,
  148. created_by_id: customer.id,
  149. updated_by_id: customer.id,
  150. )
  151. perform_enqueued_jobs commit_transaction: true
  152. end
  153. it 'adds unseen update notifications for both agents' do
  154. expect(notifications_scope('update'))
  155. .to contain_exactly(
  156. have_attributes(user: agent1, created_by: customer, seen: false),
  157. have_attributes(user: agent2, created_by: customer, seen: false)
  158. )
  159. end
  160. it_behaves_like 'destroyable notifications'
  161. end
  162. end
  163. context 'when closed ticket owner is agent and started by customer' do
  164. let(:ticket_owner) { agent1 }
  165. let(:ticket_author) { customer }
  166. let(:article_author) { customer }
  167. let(:state_name) { 'closed' }
  168. it 'adds unseen create notification for owner agent' do
  169. expect(notifications_scope('create'))
  170. .to contain_exactly(
  171. have_attributes(user: agent1, created_by: customer, seen: false)
  172. )
  173. end
  174. it_behaves_like 'destroyable notifications'
  175. context 'when customer updates a closed ticket' do
  176. before do
  177. ticket.update!(
  178. state_id: Ticket::State.lookup(name: 'open').id,
  179. priority_id: Ticket::Priority.lookup(name: '1 low').id,
  180. created_by_id: customer.id,
  181. updated_by_id: customer.id,
  182. )
  183. perform_enqueued_jobs commit_transaction: true
  184. end
  185. it 'adds unseen update notifications for owner agent' do
  186. expect(notifications_scope('update'))
  187. .to contain_exactly(
  188. have_attributes(user: agent1, created_by: customer, seen: false),
  189. )
  190. end
  191. it_behaves_like 'destroyable notifications'
  192. end
  193. end
  194. context 'when new ticket owner is system and started by agent' do
  195. let(:ticket_owner) { system }
  196. let(:ticket_author) { agent1 }
  197. let(:article_author) { agent1 }
  198. let(:state_name) { 'new' }
  199. it 'adds unseen create notification for another agent' do
  200. expect(notifications_scope('create'))
  201. .to contain_exactly(
  202. have_attributes(user: agent2, created_by: agent1, seen: false)
  203. )
  204. end
  205. it_behaves_like 'destroyable notifications'
  206. context 'when customer closes ticket' do
  207. before do
  208. ticket.update!(
  209. state_id: Ticket::State.lookup(name: 'closed').id,
  210. priority_id: Ticket::Priority.lookup(name: '1 low').id,
  211. created_by_id: customer.id,
  212. updated_by_id: customer.id,
  213. )
  214. perform_enqueued_jobs commit_transaction: true
  215. end
  216. it 'sends notifications to both agents', :aggregate_failures do
  217. expect(NotificationFactory::Mailer.already_sent?(ticket, agent1, 'update')).to eq(1)
  218. expect(NotificationFactory::Mailer.already_sent?(ticket, agent2, 'update')).to eq(1)
  219. end
  220. it 'adds seen notification to both agents' do
  221. expect(notifications_scope('update'))
  222. .to contain_exactly(
  223. have_attributes(user: agent1, created_by: customer, seen: true),
  224. have_attributes(user: agent2, created_by: customer, seen: true),
  225. )
  226. end
  227. it_behaves_like 'destroyable notifications'
  228. context 'when phone article by customer is added' do
  229. before do
  230. create(:ticket_article, :inbound_phone, ticket: ticket, updated_by: customer, created_by: customer)
  231. perform_enqueued_jobs commit_transaction: true
  232. end
  233. it 'sends notifications to both agents', :aggregate_failures do
  234. expect(NotificationFactory::Mailer.already_sent?(ticket, agent1, 'update')).to eq(2)
  235. expect(NotificationFactory::Mailer.already_sent?(ticket, agent2, 'update')).to eq(2)
  236. end
  237. it 'adds unseen notifications to both agents' do
  238. expect(notifications_scope('update'))
  239. .to contain_exactly(
  240. have_attributes(user: agent1, created_by: customer, seen: true),
  241. have_attributes(user: agent2, created_by: customer, seen: true),
  242. have_attributes(user: agent1, created_by: customer, seen: false),
  243. have_attributes(user: agent2, created_by: customer, seen: false)
  244. )
  245. end
  246. it_behaves_like 'destroyable notifications'
  247. end
  248. end
  249. end
  250. context 'when new ticket owner is agent and created by customer' do
  251. let(:ticket_owner) { agent1 }
  252. let(:ticket_author) { customer }
  253. let(:article_author) { customer }
  254. let(:state_name) { 'new' }
  255. it 'adds notification to owner agent' do
  256. expect(notifications_scope('create'))
  257. .to contain_exactly(
  258. have_attributes(user: agent1, created_by: customer, seen: false)
  259. )
  260. end
  261. it_behaves_like 'destroyable notifications'
  262. context 'when ticket is updated to open' do
  263. before do
  264. ticket.update!(
  265. state_id: Ticket::State.lookup(name: 'open').id,
  266. priority_id: Ticket::Priority.lookup(name: '1 low').id,
  267. created_by_id: customer.id,
  268. updated_by_id: customer.id,
  269. )
  270. perform_enqueued_jobs commit_transaction: true
  271. end
  272. it 'adds notification to owner agent' do
  273. expect(notifications_scope('update'))
  274. .to contain_exactly(
  275. have_attributes(user: agent1, created_by: customer, seen: false),
  276. )
  277. end
  278. it_behaves_like 'destroyable notifications'
  279. end
  280. end
  281. context 'when new ticket owner is system and created by customer' do
  282. let(:ticket_owner) { system }
  283. let(:ticket_author) { agent1 }
  284. let(:article_author) { agent1 }
  285. let(:state_name) { 'new' }
  286. it 'adds unseen notification to another agent' do
  287. expect(notifications_scope('create'))
  288. .to contain_exactly(
  289. have_attributes(user: agent2, created_by: agent1, seen: false)
  290. )
  291. end
  292. it_behaves_like 'destroyable notifications'
  293. context 'when ticket is updated by customer to open' do
  294. before do
  295. ticket.update!(
  296. state_id: Ticket::State.lookup(name: 'open').id,
  297. priority_id: Ticket::Priority.lookup(name: '1 low').id,
  298. created_by_id: customer.id,
  299. updated_by_id: customer.id,
  300. )
  301. perform_enqueued_jobs commit_transaction: true
  302. end
  303. it 'adds unseen notification to both agents' do
  304. expect(notifications_scope('update'))
  305. .to contain_exactly(
  306. have_attributes(user: agent1, created_by: customer, seen: false),
  307. have_attributes(user: agent2, created_by: customer, seen: false)
  308. )
  309. end
  310. it_behaves_like 'destroyable notifications'
  311. end
  312. end
  313. context 'when merging tickets' do
  314. let(:ticket_owner) { system }
  315. let(:ticket_author) { agent1 }
  316. let(:article_author) { agent1 }
  317. let(:state_name) { 'open' }
  318. let(:target_ticket) { create(:ticket, group: group) }
  319. before do
  320. ticket && target_ticket
  321. perform_enqueued_jobs
  322. ticket.merge_to(
  323. ticket_id: target_ticket.id,
  324. user_id: 1,
  325. )
  326. perform_enqueued_jobs
  327. end
  328. it 'notifications for origin ticket are still available' do
  329. expect(described_class.list_by_object('Ticket', ticket.id))
  330. .to be_present
  331. end
  332. it 'notifications for target ticket are still available' do
  333. expect(described_class.list_by_object('Ticket', target_ticket.id))
  334. .to be_present
  335. end
  336. it 'origin ticket has no unseen notifications' do
  337. expect(described_class.list_by_object('Ticket', ticket.id))
  338. .not_to exist(seen: false)
  339. end
  340. it 'target ticket has new notifications that are not seen notifications' do
  341. expect(described_class.list_by_object('Ticket', target_ticket.id))
  342. .to exist(seen: false)
  343. end
  344. it_behaves_like 'destroyable notifications'
  345. it_behaves_like 'destroyable notifications' do
  346. let(:destroyable_ticket) { target_ticket }
  347. end
  348. end
  349. end
  350. describe '.cleanup' do
  351. let(:max_age) { 1.week }
  352. let(:own_seen) { 1.minute }
  353. let(:auto_seen) { 10.minutes }
  354. let(:user) { create(:agent) }
  355. let(:notification) { create(:online_notification, user: user, seen: false, created_by: user) }
  356. before { notification }
  357. context 'when seen' do
  358. context 'when seen by user' do
  359. before do
  360. travel 10.minutes
  361. notification.update!(seen: true, updated_by: user)
  362. end
  363. it 'stays if it was just seen' do
  364. described_class.cleanup(max_age.ago, own_seen.ago, auto_seen.ago)
  365. expect(described_class).to exist(notification.id)
  366. end
  367. it 'deleted after own seen time passes' do
  368. travel own_seen + 1.minute
  369. described_class.cleanup(max_age.ago, own_seen.ago, auto_seen.ago)
  370. expect(described_class).not_to exist(notification.id)
  371. end
  372. end
  373. context 'when seen by another user' do
  374. before do
  375. travel 10.minutes
  376. notification.update!(seen: true)
  377. end
  378. it 'stays if it was just seen' do
  379. described_class.cleanup(max_age.ago, own_seen.ago, auto_seen.ago)
  380. expect(described_class).to exist(notification.id)
  381. end
  382. it 'not deleted after own seen time passes' do
  383. travel own_seen + 1.minute
  384. described_class.cleanup(max_age.ago, own_seen.ago, auto_seen.ago)
  385. expect(described_class).to exist(notification.id)
  386. end
  387. it 'deleted after auto seen time passes' do
  388. travel auto_seen + 1.minute
  389. described_class.cleanup(max_age.ago, own_seen.ago, auto_seen.ago)
  390. expect(described_class).not_to exist(notification.id)
  391. end
  392. end
  393. end
  394. context 'when not seen' do
  395. it 'stays if it is fresh' do
  396. described_class.cleanup(max_age.ago, own_seen.ago, auto_seen.ago)
  397. expect(described_class).to exist(notification.id)
  398. end
  399. it 'stays after own seen time passes' do
  400. travel own_seen + 1.minute
  401. described_class.cleanup(max_age.ago, own_seen.ago, auto_seen.ago)
  402. expect(described_class).to exist(notification.id)
  403. end
  404. it 'stays after auto seen time passes' do
  405. travel auto_seen + 1.minute
  406. described_class.cleanup(max_age.ago, own_seen.ago, auto_seen.ago)
  407. expect(described_class).to exist(notification.id)
  408. end
  409. it 'deleted after max time passes' do
  410. travel max_age + 1.day
  411. described_class.cleanup(max_age.ago, own_seen.ago, auto_seen.ago)
  412. expect(described_class).not_to exist(notification.id)
  413. end
  414. end
  415. describe 'notifying agents' do
  416. it 'notifies agents affected by both cleanup strategies' do
  417. agent2 = create(:agent)
  418. agent3 = create(:agent)
  419. create(:online_notification, user: user, seen: false, created_at: 1.year.ago)
  420. create(:online_notification, user: user, seen: true, updated_at: 1.month.ago)
  421. create(:online_notification, user: agent2, seen: true, updated_at: 1.month.ago)
  422. create(:online_notification, user: agent3, seen: false)
  423. allow(described_class).to receive(:cleanup_notify_agents)
  424. described_class.cleanup
  425. expect(described_class)
  426. .to have_received(:cleanup_notify_agents).with(contain_exactly(user.id, agent2.id))
  427. end
  428. end
  429. end
  430. describe '.cleanup_notify_agents' do
  431. it 'sends notifications to given users' do
  432. agent1 = create(:agent)
  433. _ = create(:agent)
  434. allow(Sessions).to receive(:send_to)
  435. described_class.cleanup_notify_agents([agent1])
  436. expect(Sessions).to have_received(:send_to).once
  437. end
  438. end
  439. describe '.seen_state?' do
  440. let(:group) { create(:group) }
  441. let(:agent1) { create(:agent, groups: [group]) }
  442. let(:agent2) { create(:agent, groups: [group]) }
  443. let(:customer) { create(:customer) }
  444. let(:system) { User.lookup(login: '-') }
  445. let(:ticket) do
  446. create(:ticket,
  447. group: group,
  448. customer: customer,
  449. owner_id: owner_id,
  450. state_name: state_name,
  451. updated_by_id: editor_id)
  452. end
  453. let(:first_article) do
  454. create(:ticket_article, :inbound_email, ticket: ticket)
  455. end
  456. context 'when state is new' do
  457. let(:state_name) { 'new' }
  458. let(:owner_id) { agent1.id }
  459. let(:editor_id) { 1 }
  460. it { expect(described_class).not_to be_seen_state(ticket) }
  461. it { expect(described_class).not_to be_seen_state(ticket, agent1.id) }
  462. it { expect(described_class).not_to be_seen_state(ticket, agent2.id) }
  463. end
  464. context 'when state is pending reminder' do
  465. let(:state_name) { 'pending reminder' }
  466. context 'when owner is an agent and updated by another agent' do
  467. let(:owner_id) { agent1.id }
  468. let(:editor_id) { agent2.id }
  469. it { expect(described_class).to be_seen_state(ticket) }
  470. it { expect(described_class).not_to be_seen_state(ticket, agent1.id) }
  471. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  472. end
  473. context 'when owner is system and updated by agent' do
  474. let(:owner_id) { 1 }
  475. let(:editor_id) { agent2.id }
  476. it { expect(described_class).to be_seen_state(ticket) }
  477. it { expect(described_class).not_to be_seen_state(ticket, agent1.id) }
  478. it { expect(described_class).not_to be_seen_state(ticket, agent2.id) }
  479. end
  480. context 'when updated by owner' do
  481. let(:owner_id) { agent1.id }
  482. let(:editor_id) { agent1.id }
  483. it { expect(described_class).to be_seen_state(ticket) }
  484. it { expect(described_class).to be_seen_state(ticket, agent1.id) }
  485. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  486. end
  487. end
  488. context 'when state is pending close' do
  489. let(:state_name) { 'pending close' }
  490. context 'when updated by owner' do
  491. let(:owner_id) { agent1.id }
  492. let(:editor_id) { agent1.id }
  493. it { expect(described_class).to be_seen_state(ticket) }
  494. it { expect(described_class).to be_seen_state(ticket, agent1.id) }
  495. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  496. end
  497. context 'when owner is an agent and updated by another agent' do
  498. let(:owner_id) { agent1.id }
  499. let(:editor_id) { agent2.id }
  500. it { expect(described_class).to be_seen_state(ticket) }
  501. it { expect(described_class).not_to be_seen_state(ticket, agent1.id) }
  502. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  503. end
  504. context 'when owner is system and updated by agent' do
  505. let(:owner_id) { 1 }
  506. let(:editor_id) { agent2.id }
  507. it { expect(described_class).to be_seen_state(ticket) }
  508. it { expect(described_class).to be_seen_state(ticket, agent1.id) }
  509. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  510. end
  511. end
  512. context 'when state is open' do
  513. let(:state_name) { 'open' }
  514. context 'when updated by owner' do
  515. let(:owner_id) { agent1.id }
  516. let(:editor_id) { agent1.id }
  517. it { expect(described_class).not_to be_seen_state(ticket) }
  518. it { expect(described_class).not_to be_seen_state(ticket, agent1.id) }
  519. it { expect(described_class).not_to be_seen_state(ticket, agent2.id) }
  520. end
  521. context 'when owner is an agent and updated by another agent' do
  522. let(:owner_id) { agent1.id }
  523. let(:editor_id) { agent2.id }
  524. it { expect(described_class).not_to be_seen_state(ticket) }
  525. it { expect(described_class).not_to be_seen_state(ticket, agent1.id) }
  526. it { expect(described_class).not_to be_seen_state(ticket, agent2.id) }
  527. end
  528. context 'when owner is system and updated by agent' do
  529. let(:owner_id) { 1 }
  530. let(:editor_id) { agent2.id }
  531. it { expect(described_class).not_to be_seen_state(ticket) }
  532. it { expect(described_class).not_to be_seen_state(ticket, agent1.id) }
  533. it { expect(described_class).not_to be_seen_state(ticket, agent2.id) }
  534. end
  535. end
  536. context 'when state is closed' do
  537. let(:state_name) { 'closed' }
  538. context 'when updated by owner' do
  539. let(:owner_id) { agent1.id }
  540. let(:editor_id) { agent1.id }
  541. it { expect(described_class).to be_seen_state(ticket) }
  542. it { expect(described_class).to be_seen_state(ticket, agent1.id) }
  543. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  544. end
  545. context 'when owner is an agent and updated by another agent' do
  546. let(:owner_id) { agent1.id }
  547. let(:editor_id) { agent2.id }
  548. it { expect(described_class).to be_seen_state(ticket) }
  549. it { expect(described_class).not_to be_seen_state(ticket, agent1.id) }
  550. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  551. end
  552. context 'when owner is system and updated by agent' do
  553. let(:owner_id) { 1 }
  554. let(:editor_id) { agent2.id }
  555. it { expect(described_class).to be_seen_state(ticket) }
  556. it { expect(described_class).to be_seen_state(ticket, agent1.id) }
  557. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  558. end
  559. end
  560. context 'when state is merged' do
  561. let(:state_name) { 'merged' }
  562. context 'when updated by owner' do
  563. let(:owner_id) { agent1.id }
  564. let(:editor_id) { agent1.id }
  565. it { expect(described_class).to be_seen_state(ticket) }
  566. it { expect(described_class).to be_seen_state(ticket, agent1.id) }
  567. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  568. end
  569. context 'when owner is an agent and updated by another agent' do
  570. let(:owner_id) { agent1.id }
  571. let(:editor_id) { agent2.id }
  572. it { expect(described_class).to be_seen_state(ticket) }
  573. it { expect(described_class).to be_seen_state(ticket, agent1.id) }
  574. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  575. end
  576. context 'when owner is system and updated by agent' do
  577. let(:owner_id) { 1 }
  578. let(:editor_id) { agent2.id }
  579. it { expect(described_class).to be_seen_state(ticket) }
  580. it { expect(described_class).to be_seen_state(ticket, agent1.id) }
  581. it { expect(described_class).to be_seen_state(ticket, agent2.id) }
  582. end
  583. end
  584. end
  585. end