123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- require 'rails_helper'
- require 'models/concerns/checks_human_changes_examples'
- RSpec.describe Transaction::Notification, type: :model do
- describe 'pending ticket reminder repeats after midnight at selected time zone' do
- let(:group) { create(:group) }
- let(:user) { create(:agent) }
- let(:ticket) { create(:ticket, owner: user, state_name: 'open', pending_time: Time.current) }
- before do
- travel_to Time.use_zone('UTC') { Time.current.noon }
- user.groups << group
- ticket
- Setting.set('timezone_default', 'America/Santiago')
- run(ticket, user, 'reminder_reached')
- OnlineNotification.destroy_all
- end
- it 'notification not sent at UTC midnight' do
- travel_to Time.use_zone('UTC') { Time.current.end_of_day + 1.minute }
- expect { run(ticket, user, 'reminder_reached') }.not_to change(OnlineNotification, :count)
- end
- it 'notification sent at selected time zone midnight' do
- travel_to Time.use_zone('America/Santiago') { Time.current.end_of_day + 1.minute }
- expect { run(ticket, user, 'reminder_reached') }.to change(OnlineNotification, :count).by(1)
- end
- end
- # https://github.com/zammad/zammad/issues/4066
- describe 'notification sending reason may be fully translated' do
- let(:group) { create(:group) }
- let(:user) { create(:agent, groups: [group]) }
- let(:ticket) { create(:ticket, owner: user, state_name: 'open', pending_time: Time.current) }
- let(:reason_en) { 'You are receiving this because you are the owner of this ticket.' }
- let(:reason_de) do
- Translation.translate('de-de', reason_en).tap do |translated|
- expect(translated).not_to eq(reason_en) # rubocop:disable RSpec/ExpectInLet
- end
- end
- before do
- allow(NotificationFactory::Mailer).to receive(:deliver)
- end
- it 'notification includes English footer' do
- run(ticket, user, 'reminder_reached')
- expect(NotificationFactory::Mailer)
- .to have_received(:deliver)
- .with hash_including body: %r{#{reason_en}}
- end
- context 'when locale set to Deutsch' do
- before do
- user.preferences[:locale] = 'de-de'
- user.save
- end
- it 'notification includes German footer' do
- run(ticket, user, 'reminder_reached')
- expect(NotificationFactory::Mailer)
- .to have_received(:deliver)
- .with hash_including body: %r{#{reason_de}}
- end
- end
- end
- describe '#ooo_replacements' do
- subject(:notification_instance) { build(ticket, user) }
- let(:group) { create(:group) }
- let(:user) { create(:agent, :ooo, :groupable, ooo_agent: replacement_1, group: group) }
- let(:ticket) { create(:ticket, owner: user, group: group, state_name: 'open', pending_time: Time.current) }
- context 'when replacement has access' do
- let(:replacement_1) { create(:agent, :groupable, group: group) }
- it 'is added to list' do
- replacements = Set.new
- ooo(notification_instance, user, replacements: replacements)
- expect(replacements).to include replacement_1
- end
- context 'when replacement has replacement' do
- let(:replacement_1) { create(:agent, :ooo, :groupable, ooo_agent: replacement_2, group: group) }
- let(:replacement_2) { create(:agent, :groupable, group: group) }
- it 'replacement\'s replacement added to list' do
- replacements = Set.new
- ooo(notification_instance, user, replacements: replacements)
- expect(replacements).to include replacement_2
- end
- it 'intermediary replacement is not in list' do
- replacements = Set.new
- ooo(notification_instance, user, replacements: replacements)
- expect(replacements).not_to include replacement_1
- end
- end
- end
- context 'when replacement does not have access' do
- let(:replacement_1) { create(:agent) }
- it 'is not added to list' do
- replacements = Set.new
- ooo(notification_instance, user, replacements: replacements)
- expect(replacements).not_to include replacement_1
- end
- context 'when replacement has replacement with access' do
- let(:replacement_1) { create(:agent, :ooo, ooo_agent: replacement_2) }
- let(:replacement_2) { create(:agent, :groupable, group: group) }
- it 'his replacement may be added' do
- replacements = Set.new
- ooo(notification_instance, user, replacements: replacements)
- expect(replacements).to include replacement_2
- end
- end
- end
- end
- describe 'SMTP errors' do
- let(:group) { create(:group) }
- let(:user) { create(:agent, groups: [group]) }
- let(:ticket) { create(:ticket, owner: user, state_name: 'open', pending_time: Time.current) }
- let(:response) { Net::SMTP::Response.new(response_status_code, 'mocked SMTP response') }
- let(:error) { Net::SMTPFatalError.new(response) }
- before do
- allow_any_instance_of(Net::SMTP).to receive(:start).and_raise(error)
- Service::System::SetEmailNotificationConfiguration
- .new(
- adapter: 'smtp',
- new_configuration: {}
- ).execute
- end
- context 'when there is a problem with the sending SMTP server' do
- let(:response_status_code) { 535 }
- it 'raises an eroror' do
- expect { run(ticket, user, 'reminder_reached') }
- .to raise_error(Channel::DeliveryError)
- end
- end
- context 'when there is a problem with the receiving SMTP server' do
- let(:response_status_code) { 550 }
- it 'logs the information about failed email delivery' do
- allow(Rails.logger).to receive(:info)
- run(ticket, user, 'reminder_reached')
- expect(Rails.logger).to have_received(:info)
- end
- end
- end
- it_behaves_like 'ChecksHumanChanges'
- def run(ticket, user, type)
- build(ticket, user, type).perform
- end
- def build(ticket, user, type = 'reminder_reached')
- described_class.new(
- object: ticket.class.name,
- type: type,
- object_id: ticket.id,
- interface_handle: 'scheduler',
- changes: nil,
- created_at: Time.current,
- user_id: user.id
- )
- end
- def ooo(instance, user, replacements: Set.new, reasons: [])
- instance.send(:ooo_replacements, user: user, replacements: replacements, ticket: ticket, reasons: reasons)
- end
- end
|