main
  1# frozen_string_literal: true
  2
  3RSpec.describe Minbox::Server do
  4  before :all do
  5    @server = Minbox::Server.new(host: "localhost", port: 8080)
  6    @server_thread = Thread.new do
  7      @server.listen! do |mail|
  8        puts mail.inspect
  9      end
 10    end
 11
 12    sleep(1)
 13  end
 14
 15  after :all do
 16    @server.shutdown!
 17    @server_thread.kill
 18  end
 19
 20  describe "#handle" do
 21    let(:host) { "localhost" }
 22    let(:port) { 8080 }
 23
 24    context "when handling a simple client" do
 25      def create_mail(to: Faker::Internet.email, from: Faker::Internet.email)
 26        Mail.new do |x|
 27          x.from from
 28          x.to to
 29          x.subject "test message"
 30          x.body "#{Time.now} This is a test message."
 31          yield x if block_given?
 32        end
 33      end
 34
 35      context "when sending a single email" do
 36        let(:result) do
 37          Net::SMTP.start(host, port) do |smtp|
 38            smtp.send_message(create_mail.to_s, Faker::Internet.email, Faker::Internet.email)
 39          end
 40        end
 41
 42        specify { expect(result).to be_success }
 43        specify { expect(result.status.to_i).to be(250) }
 44      end
 45
 46      context "when sending multiple emails" do
 47        let(:n) { rand(10) }
 48        let(:result) do
 49          Net::SMTP.start(host, port) do |smtp|
 50            n.times do
 51              smtp.send_message(create_mail.to_s, Faker::Internet.email, Faker::Internet.email)
 52            end
 53          end
 54        end
 55
 56        specify { expect(result).to eql(n) }
 57      end
 58
 59      context "with plain authentication" do
 60        let(:result) do
 61          Net::SMTP.start(host, port, "mail.from.domain", "username", "password", :plain) do |smtp|
 62            smtp.send_message(create_mail.to_s, Faker::Internet.email, Faker::Internet.email)
 63          end
 64        end
 65
 66        specify { expect(result).to be_success }
 67        specify { expect(result.status.to_i).to be(250) }
 68      end
 69
 70      context "with login authentication" do
 71        let(:result) do
 72          Net::SMTP.start(host, port, "mail.from.domain", "username", "password", :login) do |smtp|
 73            smtp.send_message(create_mail.to_s, Faker::Internet.email, Faker::Internet.email)
 74          end
 75        end
 76
 77        specify { expect(result).to be_success }
 78        specify { expect(result.status.to_i).to be(250) }
 79      end
 80
 81      context "with attachment" do
 82        let(:result) do
 83          mail = create_mail do |x|
 84            x.add_file __FILE__
 85          end
 86          Net::SMTP.start(host, port, "mail.from.domain", "username", "password", :login) do |smtp|
 87            smtp.debug_output = STDOUT
 88            smtp.send_message(mail.to_s, Faker::Internet.email, Faker::Internet.email)
 89          end
 90        end
 91
 92        specify { expect(result).to be_success }
 93        specify { expect(result.status.to_i).to be(250) }
 94      end
 95
 96      context "with html part" do
 97        let(:result) do
 98          mail = create_mail do |x|
 99            x.text_part do
100              body "this is plain text"
101            end
102            x.html_part do
103              body "<h1>this is html</h1>"
104            end
105          end
106          Net::SMTP.start(host, port) do |smtp|
107            smtp.send_message(mail.to_s, Faker::Internet.email, Faker::Internet.email)
108          end
109        end
110
111        specify { expect(result).to be_success }
112        specify { expect(result.status.to_i).to be(250) }
113      end
114
115      context "when upgrading to tls" do
116        let(:result) do
117          `(echo 'QUIT'; sleep 1) | openssl s_client -connect #{host}:#{port} -starttls smtp 2>&1`
118        end
119
120        specify { expect(result).to end_with("DONE\n") }
121        specify { expect(result).to include("250 OK") }
122      end
123
124      context "when sending multiple emails from multiple threads" do
125        let!(:email) { Faker::Internet.email }
126        let!(:mail) { create_mail }
127        let!(:mail_string) { mail.to_s }
128
129        specify do
130          threads = []
131          10.times do |_n|
132            threads << Thread.new do
133              i = rand(10)
134              result = Net::SMTP.start(host, port) do |smtp|
135                i.times do
136                  smtp.send_message(mail_string, email, email)
137                end
138              end
139              expect(result).to eql(i)
140            end
141
142            threads.map(&:join)
143          end
144        end
145      end
146    end
147  end
148end