diff options
Diffstat (limited to 'spec/lib/gitlab/mail_room')
-rw-r--r-- | spec/lib/gitlab/mail_room/authenticator_spec.rb | 20 | ||||
-rw-r--r-- | spec/lib/gitlab/mail_room/mail_room_spec.rb | 184 |
2 files changed, 183 insertions, 21 deletions
diff --git a/spec/lib/gitlab/mail_room/authenticator_spec.rb b/spec/lib/gitlab/mail_room/authenticator_spec.rb index 44120902661..2e62ed2d386 100644 --- a/spec/lib/gitlab/mail_room/authenticator_spec.rb +++ b/spec/lib/gitlab/mail_room/authenticator_spec.rb @@ -44,7 +44,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do describe '#verify_api_request' do let(:incoming_email_secret) { SecureRandom.hex(16) } let(:service_desk_email_secret) { SecureRandom.hex(16) } - let(:payload) { { iss: described_class::INTERNAL_API_REQUEST_JWT_ISSUER, iat: (Time.current - 5.minutes + 1.second).to_i } } + let(:payload) { { iss: Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER, iat: (Time.current - 5.minutes + 1.second).to_i } } before do allow(described_class).to receive(:secret).with(:incoming_email).and_return(incoming_email_secret) @@ -54,7 +54,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do context 'verify a valid token' do it 'returns the decoded payload' do encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256') - headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token } + headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token } expect(described_class.verify_api_request(headers, 'incoming_email')[0]).to match a_hash_including( "iss" => "gitlab-mailroom", @@ -62,7 +62,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do ) encoded_token = JWT.encode(payload, service_desk_email_secret, 'HS256') - headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token } + headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token } expect(described_class.verify_api_request(headers, 'service_desk_email')[0]).to match a_hash_including( "iss" => "gitlab-mailroom", @@ -74,7 +74,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do context 'verify an invalid token' do it 'returns false' do encoded_token = JWT.encode(payload, 'wrong secret', 'HS256') - headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token } + headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token } expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false) end @@ -83,7 +83,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do context 'verify a valid token but wrong mailbox type' do it 'returns false' do encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256') - headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token } + headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token } expect(described_class.verify_api_request(headers, 'service_desk_email')).to eq(false) end @@ -94,18 +94,18 @@ RSpec.describe Gitlab::MailRoom::Authenticator do it 'returns false' do encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256') - headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token } + headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token } expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false) end end context 'verify a valid token but expired' do - let(:payload) { { iss: described_class::INTERNAL_API_REQUEST_JWT_ISSUER, iat: (Time.current - 5.minutes - 1.second).to_i } } + let(:payload) { { iss: Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER, iat: (Time.current - 5.minutes - 1.second).to_i } } it 'returns false' do encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256') - headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token } + headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token } expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false) end @@ -125,7 +125,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do it 'returns false' do encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256') - headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token } + headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token } expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false) end @@ -133,7 +133,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do context 'verify headers for a non-existing mailbox type' do it 'returns false' do - headers = { described_class::INTERNAL_API_REQUEST_HEADER => 'something' } + headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => 'something' } expect(described_class.verify_api_request(headers, 'invalid_mailbox_type')).to eq(false) end diff --git a/spec/lib/gitlab/mail_room/mail_room_spec.rb b/spec/lib/gitlab/mail_room/mail_room_spec.rb index a4fcf71a012..12fb12ebd87 100644 --- a/spec/lib/gitlab/mail_room/mail_room_spec.rb +++ b/spec/lib/gitlab/mail_room/mail_room_spec.rb @@ -4,16 +4,30 @@ require 'spec_helper' RSpec.describe Gitlab::MailRoom do let(:default_port) { 143 } + let(:log_path) { Rails.root.join('log', 'mail_room_json.log').to_s } + + let(:fake_redis_queues) do + double( + url: "localhost", + db: 99, + sentinels: [{ host: 'localhost', port: 1234 }], + sentinels?: true + ) + end + let(:yml_config) do { enabled: true, + host: 'mail.example.com', address: 'address@example.com', + user: 'user@example.com', + password: 'password', port: default_port, ssl: false, start_tls: false, mailbox: 'inbox', idle_timeout: 60, - log_path: Rails.root.join('log', 'mail_room_json.log').to_s, + log_path: log_path, expunge_deleted: false } end @@ -30,6 +44,7 @@ RSpec.describe Gitlab::MailRoom do end before do + allow(Gitlab::Redis::Queues).to receive(:new).and_return(fake_redis_queues) allow(described_class).to receive(:load_yaml).and_return(configs) described_class.instance_variable_set(:@enabled_configs, nil) end @@ -39,6 +54,8 @@ RSpec.describe Gitlab::MailRoom do end describe '#enabled_configs' do + let(:first_value) { described_class.enabled_configs.each_value.first } + context 'when both email and address is set' do it 'returns email configs' do expect(described_class.enabled_configs.size).to eq(2) @@ -76,7 +93,7 @@ RSpec.describe Gitlab::MailRoom do let(:custom_config) { { enabled: true, address: 'address@example.com' } } it 'overwrites missing values with the default' do - expect(described_class.enabled_configs.each_value.first[:port]).to eq(Gitlab::MailRoom::DEFAULT_CONFIG[:port]) + expect(first_value[:port]).to eq(Gitlab::MailRoom::DEFAULT_CONFIG[:port]) end end @@ -85,23 +102,24 @@ RSpec.describe Gitlab::MailRoom do it 'returns only encoming_email' do expect(described_class.enabled_configs.size).to eq(1) - expect(described_class.enabled_configs.each_value.first[:worker]).to eq('EmailReceiverWorker') + expect(first_value[:worker]).to eq('EmailReceiverWorker') end end describe 'setting up redis settings' do - let(:fake_redis_queues) { double(url: "localhost", db: 99, sentinels: "yes, them", sentinels?: true) } - - before do - allow(Gitlab::Redis::Queues).to receive(:new).and_return(fake_redis_queues) + it 'sets delivery method to Sidekiq by default' do + config = first_value + expect(config).to include( + delivery_method: 'sidekiq' + ) end it 'sets redis config' do - config = described_class.enabled_configs.each_value.first + config = first_value expect(config).to include( redis_url: 'localhost', redis_db: 99, - sentinels: 'yes, them' + sentinels: [{ host: 'localhost', port: 1234 }] ) end end @@ -111,7 +129,7 @@ RSpec.describe Gitlab::MailRoom do let(:custom_config) { { log_path: 'tiny_log.log' } } it 'expands the log path to an absolute value' do - new_path = Pathname.new(described_class.enabled_configs.each_value.first[:log_path]) + new_path = Pathname.new(first_value[:log_path]) expect(new_path.absolute?).to be_truthy end end @@ -120,7 +138,7 @@ RSpec.describe Gitlab::MailRoom do let(:custom_config) { { log_path: '/dev/null' } } it 'leaves the path as-is' do - expect(described_class.enabled_configs.each_value.first[:log_path]).to eq '/dev/null' + expect(first_value[:log_path]).to eq '/dev/null' end end end @@ -164,4 +182,148 @@ RSpec.describe Gitlab::MailRoom do end end end + + describe 'config/mail_room.yml' do + let(:mail_room_template) { ERB.new(File.read(Rails.root.join("./config/mail_room.yml"))).result } + let(:mail_room_yml) { YAML.safe_load(mail_room_template, permitted_classes: [Symbol]) } + + shared_examples 'renders mail-specific config file correctly' do + it 'renders mail room config file correctly' do + expect(mail_room_yml[:mailboxes]).to be_an(Array) + expect(mail_room_yml[:mailboxes].length).to eq(2) + + expect(mail_room_yml[:mailboxes]).to all( + match( + a_hash_including( + host: 'mail.example.com', + port: default_port, + ssl: false, + start_tls: false, + email: 'user@example.com', + password: 'password', + idle_timeout: 60, + logger: { + log_path: log_path + }, + name: 'inbox', + + delete_after_delivery: true, + expunge_deleted: false + ) + ) + ) + end + end + + shared_examples 'renders arbitration options correctly' do + it 'renders arbitration options correctly' do + expect(mail_room_yml[:mailboxes]).to be_an(Array) + expect(mail_room_yml[:mailboxes].length).to eq(2) + expect(mail_room_yml[:mailboxes]).to all( + match( + a_hash_including( + arbitration_method: "redis", + arbitration_options: { + redis_url: "localhost", + namespace: "mail_room:gitlab", + sentinels: [{ host: "localhost", port: 1234 }] + } + ) + ) + ) + end + end + + shared_examples 'renders the sidekiq delivery method and options correctly' do + it 'renders the sidekiq delivery method and options correctly' do + expect(mail_room_yml[:mailboxes]).to be_an(Array) + expect(mail_room_yml[:mailboxes].length).to eq(2) + + expect(mail_room_yml[:mailboxes][0]).to match( + a_hash_including( + delivery_method: 'sidekiq', + delivery_options: { + redis_url: "localhost", + redis_db: 99, + namespace: "resque:gitlab", + queue: "email_receiver", + worker: "EmailReceiverWorker", + sentinels: [{ host: "localhost", port: 1234 }] + } + ) + ) + expect(mail_room_yml[:mailboxes][1]).to match( + a_hash_including( + delivery_method: 'sidekiq', + delivery_options: { + redis_url: "localhost", + redis_db: 99, + namespace: "resque:gitlab", + queue: "service_desk_email_receiver", + worker: "ServiceDeskEmailReceiverWorker", + sentinels: [{ host: "localhost", port: 1234 }] + } + ) + ) + end + end + + context 'when delivery_method is implicit' do + it_behaves_like 'renders mail-specific config file correctly' + it_behaves_like 'renders arbitration options correctly' + it_behaves_like 'renders the sidekiq delivery method and options correctly' + end + + context 'when delivery_method is explicitly sidekiq' do + let(:custom_config) { { delivery_method: 'sidekiq' } } + + it_behaves_like 'renders mail-specific config file correctly' + it_behaves_like 'renders arbitration options correctly' + it_behaves_like 'renders the sidekiq delivery method and options correctly' + end + + context 'when delivery_method is webhook (internally postback in mail_room)' do + let(:custom_config) do + { + delivery_method: 'webhook', + gitlab_url: 'http://gitlab.example', + secret_file: '/path/to/secret/file' + } + end + + it_behaves_like 'renders mail-specific config file correctly' + it_behaves_like 'renders arbitration options correctly' + + it 'renders the webhook (postback) delivery method and options correctly' do + expect(mail_room_yml[:mailboxes]).to be_an(Array) + expect(mail_room_yml[:mailboxes].length).to eq(2) + + expect(mail_room_yml[:mailboxes][0]).to match( + a_hash_including( + delivery_method: 'postback', + delivery_options: { + delivery_url: "http://gitlab.example/api/v4/internal/mail_room/incoming_email", + jwt_auth_header: Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER, + jwt_issuer: Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER, + jwt_algorithm: 'HS256', + jwt_secret_path: '/path/to/secret/file' + } + ) + ) + + expect(mail_room_yml[:mailboxes][1]).to match( + a_hash_including( + delivery_method: 'postback', + delivery_options: { + delivery_url: "http://gitlab.example/api/v4/internal/mail_room/service_desk_email", + jwt_auth_header: Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER, + jwt_issuer: Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER, + jwt_algorithm: 'HS256', + jwt_secret_path: '/path/to/secret/file' + } + ) + ) + end + end + end end |