aboutsummaryrefslogtreecommitdiffstats
path: root/actionmailbox/test/unit/router_test.rb
blob: 7eb8e04a734c443f9d700bd1edcd9d2d8b413c41 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# frozen_string_literal: true

require_relative "../test_helper"

class RootMailbox < ActionMailbox::Base
  def process
    $processed_by   = self.class.to_s
    $processed_mail = mail
  end
end

class FirstMailbox < RootMailbox
end

class SecondMailbox < RootMailbox
end

module Nested
  class FirstMailbox < RootMailbox
  end
end

class FirstMailboxAddress
  def match?(inbound_email)
    inbound_email.mail.to.include?("replies-class@example.com")
  end
end

module ActionMailbox
  class RouterTest < ActiveSupport::TestCase
    setup do
      @router = ActionMailbox::Router.new
      $processed_by = $processed_mail = nil
    end

    test "single string route" do
      @router.add_routes("first@example.com" => :first)

      inbound_email = create_inbound_email_from_mail(to: "first@example.com", subject: "This is a reply")
      @router.route inbound_email
      assert_equal "FirstMailbox", $processed_by
      assert_equal inbound_email.mail, $processed_mail
    end

    test "single string routing on cc" do
      @router.add_routes("first@example.com" => :first)

      inbound_email = create_inbound_email_from_mail(to: "someone@example.com", cc: "first@example.com", subject: "This is a reply")
      @router.route inbound_email
      assert_equal "FirstMailbox", $processed_by
      assert_equal inbound_email.mail, $processed_mail
    end

    test "single string routing on bcc" do
      @router.add_routes("first@example.com" => :first)

      inbound_email = create_inbound_email_from_mail(to: "someone@example.com", bcc: "first@example.com", subject: "This is a reply")
      @router.route inbound_email
      assert_equal "FirstMailbox", $processed_by
      assert_equal inbound_email.mail, $processed_mail
    end

    test "single string routing case-insensitively" do
      @router.add_routes("first@example.com" => :first)

      inbound_email = create_inbound_email_from_mail(to: "FIRST@example.com", subject: "This is a reply")
      @router.route inbound_email
      assert_equal "FirstMailbox", $processed_by
      assert_equal inbound_email.mail, $processed_mail
    end

    test "multiple string routes" do
      @router.add_routes("first@example.com" => :first, "second@example.com" => :second)

      inbound_email = create_inbound_email_from_mail(to: "first@example.com", subject: "This is a reply")
      @router.route inbound_email
      assert_equal "FirstMailbox", $processed_by
      assert_equal inbound_email.mail, $processed_mail

      inbound_email = create_inbound_email_from_mail(to: "second@example.com", subject: "This is a reply")
      @router.route inbound_email
      assert_equal "SecondMailbox", $processed_by
      assert_equal inbound_email.mail, $processed_mail
    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 "string route to nested mailbox" do
      @router.add_route "first@example.com", to: "nested/first"

      inbound_email = create_inbound_email_from_mail(to: "first@example.com", subject: "This is a reply")
      @router.route inbound_email
      assert_equal "Nested::FirstMailbox", $processed_by
    end

    test "all as the only route" do
      @router.add_route :all, 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 "all as the second route" do
      @router.add_route FirstMailboxAddress.new, to: :first
      @router.add_route :all, to: :second

      @router.route create_inbound_email_from_mail(to: "replies-class@example.com", subject: "This is a reply")
      assert_equal "FirstMailbox", $processed_by

      @router.route create_inbound_email_from_mail(to: "elsewhere@example.com", subject: "This is a reply")
      assert_equal "SecondMailbox", $processed_by
    end

    test "missing route" do
      assert_raises(ActionMailbox::Router::RoutingError) do
        inbound_email = create_inbound_email_from_mail(to: "going-nowhere@example.com", subject: "This is a reply")
        @router.route inbound_email
        assert inbound_email.bounced?
      end
    end

    test "invalid address" do
      assert_raises(ArgumentError) do
        @router.add_route Array.new, to: :first
      end
    end

    test "single string mailbox_for" do
      @router.add_routes("first@example.com" => :first)

      inbound_email = create_inbound_email_from_mail(to: "first@example.com", subject: "This is a reply")
      assert_equal FirstMailbox, @router.mailbox_for(inbound_email)
    end

    test "mailbox_for with no matches" do
      @router.add_routes("first@example.com" => :first)

      inbound_email = create_inbound_email_from_mail(to: "second@example.com", subject: "This is a reply")
      assert_nil @router.mailbox_for(inbound_email)
    end
  end
end