time_accounting_spec.rb 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Service::Ticket::Update::Validator::TimeAccounting do
  4. subject(:validator) { described_class.new(user: user, ticket: ticket, ticket_data: ticket_data, article_data: article_data) }
  5. let(:user) { create(:agent, groups: [group]) }
  6. let(:ticket) { create(:ticket) }
  7. let(:group) { ticket.group }
  8. let(:new_title) { Faker::Lorem.unique.word }
  9. let(:ticket_data) { { title: new_title, state: Ticket::State.find_by(name: 'new') } }
  10. let(:article_data) { nil }
  11. shared_examples 'not raising an error' do
  12. it 'does not raise an error' do
  13. expect { validator.valid! }.not_to raise_error
  14. end
  15. end
  16. shared_examples 'raising an error' do
  17. it 'raises an error' do
  18. expect { validator.valid! }.to raise_error(Service::Ticket::Update::Validator::TimeAccounting::Error, 'The ticket time accounting condition is met.')
  19. end
  20. end
  21. describe '#valid!' do
  22. it_behaves_like 'not raising an error'
  23. context 'when time accounting is enabled' do
  24. before do
  25. Setting.set('time_accounting', true)
  26. end
  27. context 'when ticket time accounting condition is met' do
  28. let(:article_type) { Ticket::Article::Type.find_by(name: 'note') }
  29. let(:article_internal) { true }
  30. let(:article_sender) { Ticket::Article::Sender.find_by(name: 'Agent') }
  31. before do
  32. Setting.set(
  33. 'time_accounting_selector',
  34. {
  35. 'condition' => {
  36. 'ticket.state_id' => { 'operator' => 'is', 'value' => [ Ticket::State.find_by(name: 'new').id.to_s ] },
  37. 'article.body' => { 'operator' => 'matches regex', 'value' => 'lipsum' },
  38. 'article.type_id' => { 'operator' => 'is', 'value' => [article_type.id] },
  39. 'article.internal' => { 'operator' => 'is', 'value' => [article_internal] },
  40. 'article.sender_id' => { 'operator' => 'is', 'value' => [article_sender.id] },
  41. }
  42. }
  43. )
  44. end
  45. it_behaves_like 'not raising an error'
  46. context 'when article is present' do
  47. let(:article_data) { { body: 'lipsum', type: article_type, internal: article_internal, sender: article_sender } }
  48. it_behaves_like 'raising an error'
  49. end
  50. context 'when article is present with time accounting data' do
  51. let(:article_data) { { body: 'lipsum', time_unit: 123 } }
  52. it_behaves_like 'not raising an error'
  53. end
  54. context 'when article is present with time accounting data set to zero' do
  55. let(:article_data) { { body: 'lipsum', time_unit: 0 } }
  56. it_behaves_like 'not raising an error'
  57. end
  58. end
  59. context 'when ticket time accounting condition is not met' do
  60. before do
  61. Setting.set('time_accounting_selector', { 'condition' => { 'ticket.state_id' => { 'operator' => 'is', 'value' => [ Ticket::State.find_by(name: 'open').id.to_s ] } } })
  62. end
  63. it_behaves_like 'not raising an error'
  64. end
  65. end
  66. end
  67. end