# frozen_string_literal: false require 'net/smtp' require 'stringio' require 'test/unit' module Net class TestSMTP < Test::Unit::TestCase class FakeSocket attr_reader :write_io def initialize out = "250 OK\n" @write_io = StringIO.new @read_io = StringIO.new out end def writeline line @write_io.write "#{line}\r\n" end def readline line = @read_io.gets raise 'ran out of input' unless line line.chop end end def test_critical smtp = Net::SMTP.new 'localhost', 25 assert_raise RuntimeError do smtp.send :critical do raise 'fail on purpose' end end assert_kind_of Net::SMTP::Response, smtp.send(:critical), '[Bug #9125]' end def test_esmtp smtp = Net::SMTP.new 'localhost', 25 assert smtp.esmtp assert smtp.esmtp? smtp.esmtp = 'omg' assert_equal 'omg', smtp.esmtp assert_equal 'omg', smtp.esmtp? end def test_rset smtp = Net::SMTP.new 'localhost', 25 smtp.instance_variable_set :@socket, FakeSocket.new assert smtp.rset end def test_mailfrom sock = FakeSocket.new smtp = Net::SMTP.new 'localhost', 25 smtp.instance_variable_set :@socket, sock assert smtp.mailfrom("foo@example.com").success? assert_equal "MAIL FROM:\r\n", sock.write_io.string end def test_rcptto sock = FakeSocket.new smtp = Net::SMTP.new 'localhost', 25 smtp.instance_variable_set :@socket, sock assert smtp.rcptto("foo@example.com").success? assert_equal "RCPT TO:\r\n", sock.write_io.string end def test_auth_plain sock = FakeSocket.new smtp = Net::SMTP.new 'localhost', 25 smtp.instance_variable_set :@socket, sock assert smtp.auth_plain("foo", "bar").success? assert_equal "AUTH PLAIN AGZvbwBiYXI=\r\n", sock.write_io.string end def test_crlf_injection smtp = Net::SMTP.new 'localhost', 25 smtp.instance_variable_set :@socket, FakeSocket.new assert_raise(ArgumentError) do smtp.mailfrom("foo\r\nbar") end assert_raise(ArgumentError) do smtp.mailfrom("foo\rbar") end assert_raise(ArgumentError) do smtp.mailfrom("foo\nbar") end assert_raise(ArgumentError) do smtp.rcptto("foo\r\nbar") end end end end