File Coverage

blib/lib/Email/Sender/Transport/Test.pm
Criterion Covered Total %
statement 41 41 100.0
branch 11 12 91.6
condition 8 9 88.8
subroutine 13 13 100.0
pod 1 8 12.5
total 74 83 89.1


line stmt bran cond sub pod time code
1             package Email::Sender::Transport::Test 2.500;
2             # ABSTRACT: deliver mail in memory for testing
3              
4 4     4   74888 use Moo;
  4         11957  
  4         35  
5              
6 4     4   4075 use Email::Sender::Failure::Multi;
  4         13  
  4         166  
7 4     4   1645 use Email::Sender::Success::Partial;
  4         12  
  4         197  
8 4     4   29 use MooX::Types::MooseLike::Base qw(ArrayRef Bool);
  4         13  
  4         2412  
9              
10             #pod =head1 DESCRIPTION
11             #pod
12             #pod This transport is meant for testing email deliveries in memory. It will store
13             #pod a record of any delivery made so that they can be inspected afterward.
14             #pod
15             #pod =for Pod::Coverage recipient_failure delivery_failure
16             #pod
17             #pod By default, the Test transport will not allow partial success and will always
18             #pod succeed. It can be made to fail predictably, however, if it is extended and
19             #pod its C or C methods are overridden. These
20             #pod methods are called as follows:
21             #pod
22             #pod $self->delivery_failure($email, $envelope);
23             #pod
24             #pod $self->recipient_failure($to);
25             #pod
26             #pod If they return true, the sending will fail. If the transport was created with
27             #pod a true C attribute, recipient failures can cause partial
28             #pod success to be returned.
29             #pod
30             #pod For more flexible failure modes, you can override more aggressively or can use
31             #pod L.
32             #pod
33             #pod =attr deliveries
34             #pod
35             #pod =for Pod::Coverage clear_deliveries
36             #pod
37             #pod This attribute stores an arrayref of all the deliveries made via the transport.
38             #pod The C method returns a list of them.
39             #pod
40             #pod Each delivery is a hashref, in the following format:
41             #pod
42             #pod {
43             #pod email => $email,
44             #pod envelope => $envelope,
45             #pod successes => \@ok_rcpts,
46             #pod failures => \@failures,
47             #pod }
48             #pod
49             #pod Both successful and failed deliveries are stored.
50             #pod
51             #pod A number of methods related to this attribute are provided:
52             #pod
53             #pod =for :list
54             #pod * delivery_count
55             #pod * clear_deliveries
56             #pod * shift_deliveries
57             #pod
58             #pod =cut
59              
60             has allow_partial_success => (is => 'ro', isa => Bool, default => sub { 0 });
61              
62       6 0   sub recipient_failure { }
63       6 0   sub delivery_failure { }
64              
65             has deliveries => (
66             isa => ArrayRef,
67             init_arg => undef,
68             default => sub { [] },
69             is => 'ro',
70             reader => '_deliveries',
71             );
72              
73 6     6 0 3472 sub delivery_count { scalar @{ $_[0]->_deliveries } }
  6         41  
74 8     8 0 18 sub record_delivery { push @{ shift->_deliveries }, @_ }
  8         30  
75 4     4 1 17 sub deliveries { @{ $_[0]->_deliveries } }
  4         50  
76 3     3 0 1350 sub shift_deliveries { shift @{ $_[0]->_deliveries } }
  3         18  
77 1     1 0 52 sub clear_deliveries { @{ $_[0]->_deliveries } = () }
  1         6  
78              
79             sub send_email {
80 13     13 0 42 my ($self, $email, $envelope) = @_;
81              
82 13         29 my @failures;
83             my @ok_rcpts;
84              
85 13 100       45 if (my $failure = $self->delivery_failure($email, $envelope)) {
86 1         1445 $failure->throw;
87             }
88              
89 12         57 for my $to (@{ $envelope->{to} }) {
  12         35  
90 14 100       47 if (my $failure = $self->recipient_failure($to)) {
91 5         6826 push @failures, $failure;
92             } else {
93 9         50 push @ok_rcpts, $to;
94             }
95             }
96              
97 12 100 100     74 if (
      100        
98             @failures
99             and ((@ok_rcpts == 0) or (! $self->allow_partial_success))
100             ) {
101 4 100 66     37 $failures[0]->throw if @failures == 1 and @ok_rcpts == 0;
102              
103 1 50       8 my $message = sprintf '%s recipients were rejected',
104             @ok_rcpts ? 'some' : 'all';
105              
106 1         11 Email::Sender::Failure::Multi->throw(
107             message => $message,
108             failures => \@failures,
109             );
110             }
111              
112             $self->record_delivery({
113 8         73 email => $email,
114             envelope => $envelope,
115             successes => \@ok_rcpts,
116             failures => \@failures,
117             });
118              
119             # XXX: We must report partial success (failures) if applicable.
120 8 100       46 return $self->success unless @failures;
121 1         25 return Email::Sender::Success::Partial->new({
122             failure => Email::Sender::Failure::Multi->new({
123             message => 'some recipients were rejected',
124             failures => \@failures
125             }),
126             });
127             }
128              
129             with 'Email::Sender::Transport';
130 4     4   42 no Moo;
  4         11  
  4         19  
131             1;
132              
133             __END__