live_users_spec.rb 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Mobile > Ticket > Viewers > Live Users', app: :mobile, authenticated_as: :agent, performs_jobs: true, type: :system do
  4. let(:group) { Group.find_by(name: 'Users') }
  5. let(:agent) { create(:agent, groups: [group]) }
  6. let(:another_agent) { create(:agent, groups: [group]) }
  7. let(:third_agent) { create(:agent, groups: [group]) }
  8. let(:customer) { create(:customer) }
  9. let(:ticket) { create(:ticket, customer: customer, group: group) }
  10. around { |example| perform_enqueued_jobs { example.run } }
  11. def wait_for_viewers_subscription(number: 1)
  12. wait_for_gql('shared/entities/ticket/graphql/subscriptions/ticketLiveUserUpdates.graphql', number: number)
  13. end
  14. def open_viewers_dialog()
  15. visit "/tickets/#{ticket.id}"
  16. wait_for_viewers_subscription
  17. find_button('Show ticket viewers').click
  18. end
  19. def update_taskbar_item(taskbar_item, state, agent_id, number)
  20. # Special case: By design, it is only allowed to update the taskbar of the current user.
  21. # We need to work around this, otherwise this test would fail.
  22. UserInfo.current_user_id = agent_id
  23. taskbar_item.update!(state: state)
  24. UserInfo.current_user_id = agent.id
  25. wait_for_viewers_subscription(number: number)
  26. end
  27. context 'when opening viewers', authenticated_as: :agent do
  28. it 'shows the users currently looking at the ticket' do
  29. taskbar_item = create(:taskbar, user_id: another_agent.id, key: "Ticket-#{ticket.id}", app: 'mobile')
  30. open_viewers_dialog
  31. # No idle viewers.
  32. expect(page).to have_no_text('Opened in tabs')
  33. # One active viewer, without editing.
  34. expect(page)
  35. .to have_text('Viewing ticket')
  36. .and have_no_text(agent.fullname)
  37. .and have_text(another_agent.fullname)
  38. .and have_no_css('.icon.icon-avatar-indicator-editing-mobile')
  39. # Checking pencil icon.
  40. update_taskbar_item(taskbar_item, { editing: true }, another_agent.id, 2)
  41. expect(page).to have_css('.icon.icon-avatar-indicator-editing-mobile')
  42. # Checking idle.
  43. travel_to 10.minutes.ago
  44. update_taskbar_item(taskbar_item, { editing: false }, another_agent.id, 3)
  45. travel_back
  46. expect(page)
  47. .to have_text('Opened in tabs')
  48. .and have_no_text(agent.fullname)
  49. .and have_no_text('Viewing ticket')
  50. .and have_text(another_agent.fullname)
  51. .and have_no_css('.icon.icon-avatar-indicator-editing-mobile')
  52. end
  53. it 'shows the users that start looking at the ticket' do
  54. visit "/tickets/#{ticket.id}"
  55. expect(page).to have_no_button('Show ticket viewers')
  56. taskbar_item = create(:taskbar, user_id: third_agent.id, key: "Ticket-#{ticket.id}", app: 'mobile')
  57. update_taskbar_item(taskbar_item, { editing: true }, third_agent.id, 1)
  58. open_viewers_dialog
  59. expect(page)
  60. .to have_text('Viewing ticket')
  61. .and have_text(third_agent.fullname)
  62. .and have_css('.icon.icon-avatar-indicator-editing-mobile')
  63. end
  64. context 'when editing is started on mobile' do
  65. it 'updates the other session' do
  66. visit "/tickets/#{ticket.id}"
  67. using_session(:customer) do
  68. login(
  69. username: another_agent.login,
  70. password: 'test',
  71. )
  72. visit "/tickets/#{ticket.id}"
  73. end
  74. open_viewers_dialog
  75. expect(page)
  76. .to have_text(another_agent.fullname)
  77. .and have_no_css('.icon.icon-avatar-indicator-editing-mobile')
  78. using_session(:customer) do
  79. visit "/tickets/#{ticket.id}/information"
  80. wait_for_form_to_settle('form-ticket-edit')
  81. within_form(form_updater_gql_number: 1) do
  82. find_input('Ticket title').type('New Title')
  83. end
  84. end
  85. wait_for_viewers_subscription(number: 2)
  86. expect(page)
  87. .to have_text('Viewing ticket')
  88. .and have_text(another_agent.fullname)
  89. .and have_css('.icon.icon-avatar-indicator-editing-mobile')
  90. end
  91. end
  92. context 'when editing is started on desktop' do
  93. it 'updates the other session' do
  94. visit "/tickets/#{ticket.id}"
  95. using_session(:customer) do
  96. login(
  97. username: another_agent.login,
  98. password: 'test',
  99. remember_me: false,
  100. app: :desktop,
  101. )
  102. visit "/#ticket/zoom/#{ticket.id}", app: :desktop
  103. end
  104. open_viewers_dialog
  105. expect(page)
  106. .to have_text(another_agent.fullname)
  107. .and have_no_css('.icon.icon-avatar-indicator-editing-desktop')
  108. using_session(:customer) do
  109. within :active_content, '.tabsSidebar' do
  110. select 'closed', from: 'State'
  111. end
  112. end
  113. wait_for_viewers_subscription(number: 2)
  114. expect(page)
  115. .to have_text('Viewing ticket')
  116. .and have_text(another_agent.fullname)
  117. .and have_css('.icon.icon-avatar-indicator-editing-desktop')
  118. end
  119. end
  120. context 'when current user is using both desktop and mobile' do
  121. it 'shows correct icons' do
  122. visit "/tickets/#{ticket.id}"
  123. using_session(:customer) do
  124. login(
  125. username: agent.login,
  126. password: 'test',
  127. remember_me: false,
  128. app: :desktop,
  129. )
  130. visit "/#ticket/zoom/#{ticket.id}", app: :desktop
  131. within :active_content, '.tabsSidebar' do
  132. select 'closed', from: 'State'
  133. end
  134. end
  135. open_viewers_dialog
  136. expect(page)
  137. .to have_text('Viewing ticket')
  138. .and have_text(agent.fullname)
  139. .and have_css('.icon.icon-avatar-indicator-editing-desktop')
  140. end
  141. end
  142. end
  143. end