diff --git a/spec/factories/channel.rb b/spec/factories/channel.rb index 2096fcb1a..498fae20a 100644 --- a/spec/factories/channel.rb +++ b/spec/factories/channel.rb @@ -80,5 +80,90 @@ FactoryBot.define do end end end + + factory :google_channel do + area { 'Google::Account' } + options do + { + 'inbound' => { + 'adapter' => 'imap', + 'options' => { + 'auth_type' => 'XOAUTH2', + 'host' => 'imap.gmail.com', + 'ssl' => true, + 'user' => ENV['GMAIL_USER'], + 'folder' => '', + 'keep_on_server' => false, + } + }, + 'outbound' => { + 'adapter' => 'smtp', + 'options' => { + 'host' => 'smtp.gmail.com', + 'domain' => 'gmail.com', + 'port' => 465, + 'ssl' => true, + 'user' => ENV['GMAIL_USER'], + 'authentication' => 'xoauth2', + } + }, + 'auth' => { + 'type' => 'XOAUTH2', + 'provider' => 'google', + 'access_token' => 'xxx', + 'expires_in' => 3599, + 'refresh_token' => ENV['GMAIL_REFRESH_TOKEN'], + 'scope' => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://mail.google.com/ openid', + 'token_type' => 'Bearer', + 'id_token' => 'xxx', + 'created_at' => 30.days.ago, + 'client_id' => ENV['GMAIL_CLIENT_ID'], + 'client_secret' => ENV['GMAIL_CLIENT_SECRET'], + } + } + end + end + + factory :microsoft365_channel do + area { 'Microsoft365::Account' } + options do + { + 'inbound' => { + 'adapter' => 'imap', + 'options' => { + 'auth_type' => 'XOAUTH2', + 'host' => 'outlook.office365.com', + 'ssl' => true, + 'user' => ENV['MICROSOFT365_USER'], + 'folder' => '', + 'keep_on_server' => false, + } + }, + 'outbound' => { + 'adapter' => 'smtp', + 'options' => { + 'host' => 'smtp.office365.com', + 'domain' => 'office365.com', + 'port' => 587, + 'user' => ENV['MICROSOFT365_USER'], + 'authentication' => 'xoauth2', + } + }, + 'auth' => { + 'type' => 'XOAUTH2', + 'provider' => 'microsoft365', + 'access_token' => 'xxx', + 'expires_in' => 3599, + 'refresh_token' => ENV['MICROSOFT365_REFRESH_TOKEN'], + 'scope' => 'https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send offline_access openid profile email', + 'token_type' => 'Bearer', + 'id_token' => 'xxx', + 'created_at' => 30.days.ago, + 'client_id' => ENV['MICROSOFT365_CLIENT_ID'], + 'client_secret' => ENV['MICROSOFT365_CLIENT_SECRET'], + } + } + end + end end end diff --git a/spec/models/channel_spec.rb b/spec/models/channel_spec.rb new file mode 100644 index 000000000..2f7ebc566 --- /dev/null +++ b/spec/models/channel_spec.rb @@ -0,0 +1,40 @@ +require 'rails_helper' + +RSpec.describe Channel, type: :model do + + context 'when authentication type is XOAUTH2' do + + shared_examples 'common XOAUTH2' do + + context 'when non-XOAUTH2 channels are present' do + + let!(:email_address) { create(:email_address, channel: create(:channel, area: 'Some::Other')) } + + before do + # XOAUTH2 channels refresh their tokens on initialization + allow(ExternalCredential).to receive(:refresh_token).and_return({ + access_token: 'S3CR3T' + }) + + channel + end + + it "doesn't remove email address assignments" do + expect { described_class.where(area: channel.area).find_each { nil } }.not_to change { email_address.reload.channel_id } + end + end + end + + context 'when provider is Google' do + it_behaves_like 'common XOAUTH2' do + let(:channel) { create(:google_channel) } + end + end + + context 'when provider is Microsoft365' do + it_behaves_like 'common XOAUTH2' do + let(:channel) { create(:microsoft365_channel) } + end + end + end +end diff --git a/spec/requests/integration/gmail_spec.rb b/spec/requests/integration/gmail_spec.rb index c41ced924..a98fc5076 100644 --- a/spec/requests/integration/gmail_spec.rb +++ b/spec/requests/integration/gmail_spec.rb @@ -1,46 +1,6 @@ require 'rails_helper' RSpec.describe 'Gmail XOAUTH2' do # rubocop:disable RSpec/DescribeClass - let(:channel) do - create(:channel, - area: 'Google::Account', - options: { - 'inbound' => { - 'adapter' => 'imap', - 'options' => { - 'auth_type' => 'XOAUTH2', - 'host' => 'imap.gmail.com', - 'ssl' => true, - 'user' => ENV['GMAIL_USER'], - 'folder' => '', - 'keep_on_server' => false, - } - }, - 'outbound' => { - 'adapter' => 'smtp', - 'options' => { - 'host' => 'smtp.gmail.com', - 'domain' => 'gmail.com', - 'port' => 465, - 'ssl' => true, - 'user' => ENV['GMAIL_USER'], - 'authentication' => 'xoauth2', - } - }, - 'auth' => { - 'type' => 'XOAUTH2', - 'provider' => 'google', - 'access_token' => 'xxx', - 'expires_in' => 3599, - 'refresh_token' => ENV['GMAIL_REFRESH_TOKEN'], - 'scope' => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://mail.google.com/ openid', - 'token_type' => 'Bearer', - 'id_token' => 'xxx', - 'created_at' => 30.days.ago, - 'client_id' => ENV['GMAIL_CLIENT_ID'], - 'client_secret' => ENV['GMAIL_CLIENT_SECRET'], - } - }) - end + let(:channel) { create(:google_channel) } before do required_envs = %w[GMAIL_REFRESH_TOKEN GMAIL_CLIENT_ID GMAIL_CLIENT_SECRET GMAIL_USER] @@ -62,17 +22,4 @@ RSpec.describe 'Gmail XOAUTH2' do # rubocop:disable RSpec/DescribeClass expect(result[:result]).to eq('ok') end end - - context 'when non-Google channels are present' do - - let!(:email_address) { create(:email_address, channel: create(:channel, area: 'Some::Other')) } - - before do - channel - end - - it "doesn't remove email address assignments" do - expect { Channel.where(area: 'Google::Account').find_each { nil } }.not_to change { email_address.reload.channel_id } - end - end end diff --git a/spec/requests/integration/microsoft365_spec.rb b/spec/requests/integration/microsoft365_spec.rb index 3e11415ec..0ab596aa0 100644 --- a/spec/requests/integration/microsoft365_spec.rb +++ b/spec/requests/integration/microsoft365_spec.rb @@ -1,45 +1,6 @@ require 'rails_helper' RSpec.describe 'Microsoft365 XOAUTH2' do # rubocop:disable RSpec/DescribeClass - let(:channel) do - create(:channel, - area: 'Microsoft365::Account', - options: { - 'inbound' => { - 'adapter' => 'imap', - 'options' => { - 'auth_type' => 'XOAUTH2', - 'host' => 'outlook.office365.com', - 'ssl' => true, - 'user' => ENV['MICROSOFT365_USER'], - 'folder' => '', - 'keep_on_server' => false, - } - }, - 'outbound' => { - 'adapter' => 'smtp', - 'options' => { - 'host' => 'smtp.office365.com', - 'domain' => 'office365.com', - 'port' => 587, - 'user' => ENV['MICROSOFT365_USER'], - 'authentication' => 'xoauth2', - } - }, - 'auth' => { - 'type' => 'XOAUTH2', - 'provider' => 'microsoft365', - 'access_token' => 'xxx', - 'expires_in' => 3599, - 'refresh_token' => ENV['MICROSOFT365_REFRESH_TOKEN'], - 'scope' => 'https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send offline_access openid profile email', - 'token_type' => 'Bearer', - 'id_token' => 'xxx', - 'created_at' => 30.days.ago, - 'client_id' => ENV['MICROSOFT365_CLIENT_ID'], - 'client_secret' => ENV['MICROSOFT365_CLIENT_SECRET'], - } - }) - end + let(:channel) { create(:microsoft365_channel) } before do required_envs = %w[MICROSOFT365_REFRESH_TOKEN MICROSOFT365_CLIENT_ID MICROSOFT365_CLIENT_SECRET MICROSOFT365_USER] @@ -61,17 +22,4 @@ RSpec.describe 'Microsoft365 XOAUTH2' do # rubocop:disable RSpec/DescribeClass expect(result[:result]).to eq('ok') end end - - context 'when non-Microsoft365 channels are present' do - - let!(:email_address) { create(:email_address, channel: create(:channel, area: 'Some::Other')) } - - before do - channel - end - - it "doesn't remove email address assignments" do - expect { Channel.where(area: 'Microsoft365::Account').find_each { nil } }.not_to change { email_address.reload.channel_id } - end - end end