mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Expand router with real routing object and 4-way address options
This commit is contained in:
parent
2d6c79413d
commit
d14f54b0e0
4 changed files with 89 additions and 4 deletions
|
@ -1,20 +1,34 @@
|
||||||
class ActionMailroom::Router
|
class ActionMailroom::Router
|
||||||
|
class RoutingError < StandardError; end
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@routes = {}
|
@routes = []
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_routes(routes)
|
def add_routes(routes)
|
||||||
@routes.merge!(routes)
|
routes.each do |(address, mailbox_name)|
|
||||||
|
add_route address, to: mailbox_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_route(address, to:)
|
||||||
|
routes.append Route.new(address, to: to)
|
||||||
end
|
end
|
||||||
|
|
||||||
def route(inbound_email)
|
def route(inbound_email)
|
||||||
locate_mailbox(inbound_email).receive(inbound_email)
|
if mailbox = locate_mailbox(inbound_email)
|
||||||
|
mailbox.receive(inbound_email)
|
||||||
|
else
|
||||||
|
raise RoutingError
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
attr_reader :routes
|
attr_reader :routes
|
||||||
|
|
||||||
def locate_mailbox(inbound_email)
|
def locate_mailbox(inbound_email)
|
||||||
"#{routes[inbound_email.mail.to.first].to_s.capitalize}Mailbox".constantize
|
routes.detect { |route| route.match?(inbound_email) }.try(:mailbox_class)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
require "action_mailroom/router/route"
|
||||||
|
|
26
lib/action_mailroom/router/route.rb
Normal file
26
lib/action_mailroom/router/route.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
class ActionMailroom::Router::Route
|
||||||
|
class InvalidAddressError < StandardError; end
|
||||||
|
|
||||||
|
attr_reader :address, :mailbox_name
|
||||||
|
|
||||||
|
def initialize(address, to:)
|
||||||
|
@address, @mailbox_name = address, to
|
||||||
|
end
|
||||||
|
|
||||||
|
def match?(inbound_email)
|
||||||
|
case address
|
||||||
|
when String
|
||||||
|
inbound_email.mail.to.include?(address)
|
||||||
|
when Regexp
|
||||||
|
inbound_email.mail.to.detect { |recipient| address.match?(recipient) }
|
||||||
|
when Proc
|
||||||
|
address.call(inbound_email)
|
||||||
|
else
|
||||||
|
address.try(:match?, inbound_email) || raise(InvalidAddressError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def mailbox_class
|
||||||
|
"#{mailbox_name.to_s.capitalize}Mailbox".constantize
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,3 +1,5 @@
|
||||||
|
require "mail"
|
||||||
|
|
||||||
module ActionMailroom
|
module ActionMailroom
|
||||||
module TestHelper
|
module TestHelper
|
||||||
# Create an InboundEmail record using an eml fixture in the format of message/rfc822
|
# Create an InboundEmail record using an eml fixture in the format of message/rfc822
|
||||||
|
|
|
@ -13,6 +13,12 @@ end
|
||||||
class SecondMailbox < RootMailbox
|
class SecondMailbox < RootMailbox
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class FirstMailboxAddress
|
||||||
|
def match?(inbound_email)
|
||||||
|
inbound_email.mail.to.include?("replies-class@example.com")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
module ActionMailroom
|
module ActionMailroom
|
||||||
class RouterTest < ActiveSupport::TestCase
|
class RouterTest < ActiveSupport::TestCase
|
||||||
setup do
|
setup do
|
||||||
|
@ -42,5 +48,42 @@ module ActionMailroom
|
||||||
assert_equal "SecondMailbox", $processed_by
|
assert_equal "SecondMailbox", $processed_by
|
||||||
assert_equal inbound_email.mail, $processed_mail
|
assert_equal inbound_email.mail, $processed_mail
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "single regexp route" do
|
||||||
|
@router.add_routes(/replies-\w+@example.com/ => :first, "replies-nowhere@example.com" => :second)
|
||||||
|
|
||||||
|
inbound_email = create_inbound_email_from_mail(to: "replies-okay@example.com", subject: "This is a reply")
|
||||||
|
@router.route inbound_email
|
||||||
|
assert_equal "FirstMailbox", $processed_by
|
||||||
|
end
|
||||||
|
|
||||||
|
test "single proc route" do
|
||||||
|
@router.add_route \
|
||||||
|
->(inbound_email) { inbound_email.mail.to.include?("replies-proc@example.com") },
|
||||||
|
to: :second
|
||||||
|
|
||||||
|
@router.route create_inbound_email_from_mail(to: "replies-proc@example.com", subject: "This is a reply")
|
||||||
|
assert_equal "SecondMailbox", $processed_by
|
||||||
|
end
|
||||||
|
|
||||||
|
test "address class route" do
|
||||||
|
@router.add_route FirstMailboxAddress.new, to: :first
|
||||||
|
@router.route create_inbound_email_from_mail(to: "replies-class@example.com", subject: "This is a reply")
|
||||||
|
assert_equal "FirstMailbox", $processed_by
|
||||||
|
end
|
||||||
|
|
||||||
|
test "missing route" do
|
||||||
|
assert_raises(ActionMailroom::Router::RoutingError) do
|
||||||
|
inbound_email = create_inbound_email_from_mail(to: "going-nowhere@example.com", subject: "This is a reply")
|
||||||
|
@router.route inbound_email
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "invalid address" do
|
||||||
|
assert_raises(ActionMailroom::Router::Route::InvalidAddressError) do
|
||||||
|
@router.add_route Array.new, to: :first
|
||||||
|
@router.route create_inbound_email_from_mail(to: "replies-nowhere@example.com", subject: "This is a reply")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue