escalation_spec.rb 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Ticket Escalation', type: :request do
  4. let(:sla_first_response) { 1.hour }
  5. let(:sla_response) { 3.hours }
  6. let(:sla_close) { 4.hours }
  7. let!(:mail_group) { create(:group, email_address: create(:email_address)) }
  8. let(:calendar) { create(:calendar, :'24/7') }
  9. let(:sla) do
  10. create(:sla,
  11. calendar: calendar,
  12. first_response_time: sla_first_response / 1.minute,
  13. response_time: sla_response / 1.minute,
  14. solution_time: sla_close / 1.minute)
  15. end
  16. define :json_equal_date do
  17. match do
  18. actual&.sub(%r{.\d\d\dZ$}, 'Z') == expected&.iso8601
  19. end
  20. end
  21. shared_examples 'response matching object' do
  22. %w[escalation_at first_response_escalation_at update_escalation_at close_escalation_at].each do |attribute|
  23. it "#{attribute} is representing the same time" do
  24. expect(json_response[attribute]).to json_equal_date ticket[attribute]
  25. end
  26. end
  27. end
  28. before do
  29. freeze_time
  30. sla
  31. end
  32. context 'when customer creates ticket via web', authenticated_as: :customer do
  33. subject(:ticket) { Ticket.find(json_response['id']) }
  34. let(:customer) { create(:customer) }
  35. before do
  36. params = {
  37. title: 'some value 123',
  38. group: mail_group.name,
  39. article: {
  40. type_id: Ticket::Article::Type.find_by(name: 'web').id,
  41. body: 'some test 123',
  42. },
  43. }
  44. post '/api/v1/tickets', params: params, as: :json
  45. end
  46. it_behaves_like 'response matching object'
  47. it 'first response escalation in 1h' do
  48. expect(ticket.first_response_escalation_at).to eq 1.hour.from_now
  49. end
  50. it 'update_escalation in 3h' do
  51. expect(ticket.update_escalation_at).to eq 3.hours.from_now
  52. end
  53. it 'close escalation in 4h' do
  54. expect(ticket.close_escalation_at).to eq 4.hours.from_now
  55. end
  56. it 'next escalation is closest escalation' do
  57. expect(ticket.escalation_at).to eq 1.hour.from_now
  58. end
  59. end
  60. context 'when customer sends email' do
  61. subject(:ticket) { ticket_mail_in }
  62. before { ticket }
  63. it 'first response escalation in 1h' do
  64. expect(ticket.first_response_escalation_at).to eq 1.hour.from_now
  65. end
  66. it 'update_escalation in 3h' do
  67. expect(ticket.update_escalation_at).to eq 3.hours.from_now
  68. end
  69. it 'close escalation in 4h' do
  70. expect(ticket.close_escalation_at).to eq 4.hours.from_now
  71. end
  72. it 'next escalation is closest escalation' do
  73. expect(ticket.escalation_at).to eq 1.hour.from_now
  74. end
  75. end
  76. context 'when agent responds via web', authenticated_as: :agent do
  77. subject(:ticket) { ticket_mail_in }
  78. let(:agent) { create(:agent, groups: Group.all) }
  79. before { ticket && travel(3.hours) }
  80. it_behaves_like 'response matching object' do
  81. before { ticket_respond_web }
  82. end
  83. it 'clears first response escalation' do
  84. expect { ticket_respond_web }.to change(ticket, :first_response_escalation_at).to(nil)
  85. end
  86. it 'changes update escalation' do
  87. expect { ticket_respond_web }.to change(ticket, :update_escalation_at)
  88. end
  89. it 'update escalation is nil since agent responded' do
  90. ticket_respond_web
  91. expect(ticket.update_escalation_at).to be_nil
  92. end
  93. it 'does not change close escalation' do
  94. expect { ticket_respond_web }.not_to change(ticket, :close_escalation_at)
  95. end
  96. it 'change next escalation' do
  97. expect { ticket_respond_web }.to change(ticket, :escalation_at)
  98. end
  99. it 'next escalation is closest escalation which is close escalation' do
  100. ticket_respond_web
  101. expect(ticket.escalation_at).to eq 1.hour.from_now
  102. end
  103. def ticket_respond_web
  104. params = {
  105. title: 'some value 123 - update',
  106. article: {
  107. type_id: Ticket::Article::Type.find_by(name: 'email').id,
  108. body: 'some test 123',
  109. type: 'email',
  110. to: 'customer@example.com',
  111. },
  112. }
  113. put "/api/v1/tickets/#{ticket.id}", params: params, as: :json
  114. ticket.reload
  115. end
  116. end
  117. def ticket_mail_in
  118. email = <<~EMAIL
  119. From: Bob Smith <customer@example.com>
  120. To: #{mail_group.email_address.email}
  121. Subject: some value 123
  122. Some Text
  123. EMAIL
  124. ticket, _article_p, _user_p, _mail = Channel::EmailParser.new.process({}, email)
  125. ticket
  126. end
  127. end