ticket_articles_spec.rb 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Mobile > Ticket > Articles', app: :mobile, authenticated_as: :agent, type: :system do
  4. let(:group) { create(:group) }
  5. let(:agent) { create(:agent, groups: [group]) }
  6. before do
  7. article if defined?(article)
  8. articles if defined?(articles)
  9. visit "/tickets/#{ticket.id}"
  10. wait_for_form_to_settle('form-ticket-edit')
  11. end
  12. context 'when opening ticket with a single article' do
  13. let(:ticket) { create(:ticket, title: 'Ticket Title', group: group) }
  14. let(:article) { create(:ticket_article, body: 'Article 1', ticket: ticket, internal: false) }
  15. it 'see a single article and no "load more"' do
  16. expect(page).to have_text(article.body)
  17. expect(page).to have_no_text('load')
  18. end
  19. it 'switches article to internal' do
  20. find('[data-name="article-context"]').click
  21. click_on 'Set to internal'
  22. wait_for_gql('shared/entities/ticket-article/graphql/mutations/changeVisibility.graphql')
  23. expect(page).to have_css('.Article.Internal')
  24. end
  25. context 'when article is deletable', current_user_id: -> { agent.id } do
  26. let(:article) { create(:ticket_article, :internal_note, body: 'Article 1', ticket: ticket) }
  27. it 'deletes article' do
  28. find('[data-name="article-context"]').click
  29. click_on 'Delete Article'
  30. click_on 'OK'
  31. expect(page).to have_no_text(article.body)
  32. end
  33. end
  34. end
  35. context 'when opening ticket with 6 articles page' do
  36. let(:ticket) { create(:ticket, title: 'Ticket Title', group: group) }
  37. let(:articles) do
  38. (1..6).map do |number|
  39. create(:ticket_article, body: "Article #{number}", ticket: ticket)
  40. end
  41. end
  42. it 'see all 6 articles' do
  43. articles.each do |article|
  44. expect(page).to have_text(article.body, count: 1)
  45. end
  46. expect(page).to have_no_text('load')
  47. end
  48. end
  49. context 'when opening ticket with a lot of articles' do
  50. let(:customer) { create(:customer) }
  51. let(:ticket) { create(:ticket, title: 'Ticket Title', group: group) }
  52. let(:articles) do
  53. create_list(:ticket_article, 10, ticket: ticket, content_type: 'text/html').tap do |articles|
  54. articles.each_with_index do |article, index|
  55. body = "Article #{index + 1}."
  56. body += "<a href='/mobile/users/#{customer.id}'>UserLink</a>" if index == 3
  57. # last article is deletable
  58. internal = index == articles.length - 1
  59. article.update!(body: body, internal: internal)
  60. end
  61. end
  62. end
  63. it 'deleting article if every article is loaded', current_user_id: -> { agent.id } do
  64. click('button', text: 'load 4 more')
  65. wait_for_gql('shared/entities/ticket/graphql/queries/ticket/articles.graphql')
  66. expect(page).to have_text(articles.last.body)
  67. # Ensure to scroll to the bottom of the page before clicking the context menu.
  68. page.scroll_to :bottom
  69. all('[data-name="article-context"]').last.click
  70. expect(page).to have_button('Delete Article')
  71. click_on 'Delete Article'
  72. click_on 'OK'
  73. expect(page).to have_no_text(articles.last.body)
  74. end
  75. it 'can use "load more" button' do
  76. expect(page).to have_text('Article 1.')
  77. (6..10).each do |number|
  78. expect(page).to have_text("Article #{number}.", count: 1)
  79. end
  80. expect(page).to have_no_text('Article 5.')
  81. click('button', text: 'load 4 more')
  82. wait_for_gql('shared/entities/ticket/graphql/queries/ticket/articles.graphql')
  83. (1..5).each do |number|
  84. expect(page).to have_text("Article #{number}.", count: 1)
  85. end
  86. expect(page).to have_no_text('load')
  87. end
  88. it 'can go back to the same spot' do
  89. expect(page).to have_text('Article 1.')
  90. expect(page).to have_no_text('Article 5.')
  91. click('button', text: 'load 4 more')
  92. page.scroll_to 0, 100
  93. expect(page).to have_text('Article 2.', count: 1)
  94. link = find_link('UserLink')
  95. position_old = link.evaluate_script('this.getBoundingClientRect().top')
  96. link.click
  97. find_button('Go back').click
  98. expect_current_route "/tickets/#{ticket.id}"
  99. position_new = find_link('UserLink').evaluate_script('this.getBoundingClientRect().top')
  100. expect(position_old).to eq(position_new)
  101. end
  102. end
  103. context 'when retrying security' do
  104. let(:ticket) do
  105. # Import S/MIME mail without certificates present.
  106. Setting.set('smime_integration', true)
  107. smime_mail = Rails.root.join('spec/fixtures/files/smime/sender_is_signer.eml').read
  108. allow(ARGF).to receive(:read).and_return(smime_mail)
  109. Channel::Driver::MailStdin.new
  110. Ticket.last
  111. end
  112. let(:agent) { create(:agent, groups: [ticket.group]) }
  113. it 'updates state on successful retry' do
  114. create(:smime_certificate, :with_private, fixture: 'smime1@example.com')
  115. find_button('Security Error').click
  116. find_button('Try again').click
  117. # visually updates state
  118. expect(find('[aria-label="Signed"]')).to be_present
  119. expect(page).to have_text('The signature was successfully verified.')
  120. expect(page).to have_no_text('Security Error')
  121. end
  122. it 'shows error on unsucessful retry' do
  123. find_button('Security Error').click
  124. find_button('Try again').click
  125. expect(page).to have_text('The certificate for verification could not be found.')
  126. expect(page).to have_text('Security Error')
  127. expect(page).to have_no_css('[aria-label="Signed"]')
  128. end
  129. end
  130. end