channel_spec.rb 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Channel, type: :model do
  4. describe '.fetch' do
  5. describe '#refresh_xoauth2! fails' do
  6. let(:channel) { create(:channel, area: 'SomeXOAUTH2::Account', options: { adapter: 'DummyXOAUTH2', auth: { type: 'XOAUTH2' } }) }
  7. before do
  8. allow(ExternalCredential).to receive(:refresh_token).and_raise(RuntimeError)
  9. end
  10. it 'changes Channel status to error' do
  11. expect { described_class.fetch }.to change { channel.reload.status_in }.to('error')
  12. end
  13. end
  14. context 'when one adapter fetch fails' do
  15. let(:failing_adapter_class) do
  16. Class.new(Channel::Driver::Null) do
  17. def fetchable?(...)
  18. true
  19. end
  20. def fetch(...)
  21. raise 'some error'
  22. end
  23. end
  24. end
  25. let(:dummy_adapter_class) do
  26. Class.new(Channel::Driver::Null) do
  27. def fetchable?(...)
  28. true
  29. end
  30. end
  31. end
  32. let(:failing_channel) do
  33. create(:email_channel, inbound: {
  34. adapter: 'failing',
  35. options: {}
  36. })
  37. end
  38. let(:other_channel) do
  39. create(:email_channel, inbound: {
  40. adapter: 'dummy',
  41. options: {}
  42. })
  43. end
  44. before do
  45. allow(described_class).to receive(:driver_class).with('dummy').and_return(dummy_adapter_class)
  46. allow(described_class).to receive(:driver_class).with('failing').and_return(failing_adapter_class)
  47. failing_channel
  48. other_channel
  49. end
  50. it 'adds error flag to the failing Channel' do
  51. expect { described_class.fetch }.to change { failing_channel.reload.preferences[:last_fetch] }.and change { failing_channel.reload.status_in }.to('error')
  52. end
  53. it 'fetches others anyway' do
  54. expect { described_class.fetch }.to change { other_channel.reload.preferences[:last_fetch] }.and change { other_channel.reload.status_in }.to('ok')
  55. end
  56. end
  57. end
  58. context 'when authentication type is XOAUTH2' do
  59. shared_examples 'common XOAUTH2' do
  60. context 'when token refresh fails' do
  61. let(:exception) { DummyExternalCredentialsBackendError.new('something unexpected happened here') }
  62. before do
  63. stub_const('DummyExternalCredentialsBackendError', Class.new(StandardError))
  64. allow(ExternalCredential).to receive(:refresh_token).and_raise(exception)
  65. end
  66. it 'raises RuntimeError' do
  67. expect { channel.refresh_xoauth2! }.to raise_exception(RuntimeError, %r{#{exception.message}})
  68. end
  69. end
  70. context 'when non-XOAUTH2 channels are present' do
  71. let!(:email_address) { create(:email_address, channel: create(:channel, area: 'Some::Other')) }
  72. before do
  73. # XOAUTH2 channels refresh their tokens on initialization
  74. allow(ExternalCredential).to receive(:refresh_token).and_return({
  75. access_token: 'S3CR3T'
  76. })
  77. channel
  78. end
  79. it "doesn't remove email address assignments" do
  80. expect { described_class.where(area: channel.area).find_each { nil } }.not_to change { email_address.reload.channel_id }
  81. end
  82. end
  83. end
  84. context 'when provider is Google' do
  85. it_behaves_like 'common XOAUTH2' do
  86. let(:channel) { create(:google_channel) }
  87. end
  88. end
  89. context 'when provider is Microsoft365' do
  90. it_behaves_like 'common XOAUTH2' do
  91. let(:channel) { create(:microsoft365_channel) }
  92. end
  93. end
  94. end
  95. describe 'validations' do
  96. it 'validates email account uniqueness' do
  97. expect_any_instance_of(Validations::ChannelEmailAccountUniquenessValidator)
  98. .to receive(:validate).once
  99. create(:email_channel)
  100. end
  101. end
  102. end