# frozen_string_literal: true RSpec.describe EmailSettingsValidator do let(:username) { "kwest@gmail.com" } let(:password) { "mbdtf" } describe "#validate_imap" do let(:host) { "imap.gmail.com" } let(:port) { 993 } let(:net_imap_stub) do obj = mock() obj.stubs(:login).returns(true) obj end before { Net::IMAP.stubs(:new).returns(net_imap_stub) } it "is valid if no error is raised" do net_imap_stub.stubs(:logout).returns(true) net_imap_stub.stubs(:disconnect).returns(true) expect { described_class.validate_imap( host: host, port: port, username: username, password: password, ) }.not_to raise_error end it "is invalid if an error is raised" do net_imap_stub.stubs(:login).raises( Net::IMAP::NoResponseError, stub(data: stub(text: "no response")), ) expect { described_class.validate_imap( host: host, port: port, username: username, password: password, debug: true, ) }.to raise_error(Net::IMAP::NoResponseError) end it "logs a warning if debug: true passed in and still raises the error" do net_imap_stub.stubs(:login).raises( Net::IMAP::NoResponseError, stub(data: stub(text: "no response")), ) Rails .logger .expects(:warn) .with(regexp_matches(/\[EmailSettingsValidator\] Error encountered/)) .at_least_once expect { described_class.validate_imap( host: host, port: port, username: username, password: password, debug: true, ) }.to raise_error(Net::IMAP::NoResponseError) end end describe "#validate_pop3" do let(:host) { "pop.gmail.com" } let(:port) { 995 } let(:net_pop3_stub) do obj = mock() obj.stubs(:auth_only).returns(true) obj.stubs(:enable_ssl).returns(true) obj end before { Net::POP3.stubs(:new).returns(net_pop3_stub) } it "is valid if no error is raised" do expect { described_class.validate_pop3( host: host, port: port, username: username, password: password, ) }.not_to raise_error end it "is invalid if an error is raised" do net_pop3_stub.stubs(:auth_only).raises(Net::POPAuthenticationError, "invalid credentials") expect { described_class.validate_pop3( host: host, port: port, username: username, password: password, debug: true, ) }.to raise_error(Net::POPAuthenticationError) end it "logs a warning if debug: true passed in and still raises the error" do Rails .logger .expects(:warn) .with(regexp_matches(/\[EmailSettingsValidator\] Error encountered/)) .at_least_once net_pop3_stub.stubs(:auth_only).raises(Net::POPAuthenticationError, "invalid credentials") expect { described_class.validate_pop3( host: host, port: port, username: username, password: password, debug: true, ) }.to raise_error(Net::POPAuthenticationError) end it "uses the correct ssl verify params if those settings are enabled" do SiteSetting.pop3_polling_ssl = true SiteSetting.pop3_polling_openssl_verify = true net_pop3_stub.expects(:enable_ssl).with(max_version: OpenSSL::SSL::TLS1_2_VERSION) expect { described_class.validate_pop3( host: host, port: port, username: username, password: password, ) }.not_to raise_error end it "uses the correct ssl verify params if openssl_verify is not enabled" do SiteSetting.pop3_polling_ssl = true SiteSetting.pop3_polling_openssl_verify = false net_pop3_stub.expects(:enable_ssl).with(OpenSSL::SSL::VERIFY_NONE) expect { described_class.validate_pop3( host: host, port: port, username: username, password: password, ) }.not_to raise_error end end describe "#validate_smtp" do let(:host) { "smtp.gmail.com" } let(:port) { 587 } let(:domain) { "gmail.com" } let(:net_smtp_stub) do obj = mock() obj.stubs(:start).returns(true) obj.stubs(:finish).returns(true) obj.stubs(:enable_tls).returns(true) obj.stubs(:enable_starttls_auto).returns(true) obj.stubs(:open_timeout=) obj.stubs(:read_timeout=) obj end before { Net::SMTP.stubs(:new).returns(net_smtp_stub) } it "is valid if no error is raised" do expect { described_class.validate_smtp( host: host, port: port, username: username, password: password, domain: domain, ) }.not_to raise_error end it "is invalid if an error is raised" do net_smtp_stub.stubs(:start).raises(Net::SMTPAuthenticationError, "invalid credentials") expect { described_class.validate_smtp( host: host, port: port, username: username, password: password, domain: domain, ) }.to raise_error(Net::SMTPAuthenticationError) end it "logs a warning if debug: true passed in and still raises the error" do Rails .logger .expects(:warn) .with(regexp_matches(/\[EmailSettingsValidator\] Error encountered/)) .at_least_once net_smtp_stub.stubs(:start).raises( Net::SMTPAuthenticationError, stub(message: "invalid credentials"), ) expect { described_class.validate_smtp( host: host, port: port, username: username, password: password, debug: true, domain: domain, ) }.to raise_error(Net::SMTPAuthenticationError) end it "uses the correct ssl verify params for enable_tls if those settings are enabled" do net_smtp_stub.expects(:enable_tls) expect { described_class.validate_smtp( host: host, port: 465, username: username, password: password, domain: domain, openssl_verify_mode: "peer", enable_tls: true, enable_starttls_auto: false, ) }.not_to raise_error end it "uses the correct ssl verify params for enable_starttls_auto if those settings are enabled" do net_smtp_stub.expects(:enable_starttls_auto) expect { described_class.validate_smtp( host: host, port: 587, username: username, password: password, domain: domain, openssl_verify_mode: "peer", enable_tls: false, enable_starttls_auto: true, ) }.not_to raise_error end it "raises an ArgumentError if both enable_tls is true and enable_starttls_auto is true" do expect { described_class.validate_smtp( host: host, port: port, username: username, password: password, domain: domain, enable_ssl: true, enable_starttls_auto: true, ) }.to raise_error(ArgumentError) end it "raises an ArgumentError if a bad authentication method is used" do expect { described_class.validate_smtp( host: host, port: port, username: username, password: password, domain: domain, authentication: :rubber_stamp, ) }.to raise_error(ArgumentError) end it "corrects authentication method to login for office365" do net_smtp_stub.expects(:start).with("office365.com", username, password, :login) described_class.validate_smtp( host: "smtp.office365.com", port: port, username: username, password: password, domain: "office365.com", ) end it "corrects authentication method to login for outlook" do net_smtp_stub.expects(:start).with("outlook.com", username, password, :login) described_class.validate_smtp( host: "smtp-mail.outlook.com", port: port, username: username, password: password, domain: "outlook.com", ) end context "when the domain is not provided" do let(:domain) { nil } it "gets the domain from the host" do net_smtp_stub.expects(:start).with("gmail.com", username, password, :plain) described_class.validate_smtp( host: host, port: port, username: username, password: password, enable_tls: true, enable_starttls_auto: false, ) end it "uses localhost when in development mode" do Rails.env.stubs(:development?).returns(true) net_smtp_stub.expects(:start).with("localhost", username, password, :plain) described_class.validate_smtp( host: host, port: port, username: username, password: password, enable_tls: true, enable_starttls_auto: false, ) end end end end