File Coverage

blib/lib/Email/Folder/Search.pm
Criterion Covered Total %
statement 68 70 97.1
branch 8 10 80.0
condition 12 19 63.1
subroutine 12 12 100.0
pod 5 5 100.0
total 105 116 90.5


line stmt bran cond sub pod time code
1             package Email::Folder::Search;
2              
3             # ABSTRACT: wait and search emails from mailbox
4              
5             =head1 NAME
6              
7             Email::Folder::Search - wait and search emails from mailbox
8              
9             =head1 DESCRIPTION
10              
11             Search email from mailbox file. This module is mainly to test that the emails are received or not.
12              
13             =head1 SYNOPSIS
14              
15             use Email::Folder::Search;
16             my $folder = Email::Folder::Search->new('/var/spool/mbox');
17             my %msg = $folder->search(email => 'hello@test.com', subject => qr/this is a subject/);
18             $folder->clear();
19              
20             =cut
21              
22             =head1 Methods
23              
24             =cut
25              
26 1     1   29504 use strict;
  1         3  
  1         22  
27 1     1   4 use warnings;
  1         2  
  1         22  
28 1     1   398 use Encode qw(decode);
  1         7188  
  1         58  
29 1     1   6 use Scalar::Util qw(blessed);
  1         2  
  1         52  
30 1     1   5 use base 'Email::Folder';
  1         3  
  1         326  
31 1     1   12699 use Email::MIME;
  1         30068  
  1         23  
32 1     1   337 use mro;
  1         524  
  1         4  
33              
34             our $VERSION = '0.012';
35              
36             =head2 new($folder, %options)
37              
38             takes the name of a folder, and a hash of options
39              
40             options:
41              
42             =over
43              
44             =item timeout
45              
46             The seconds that search will wait if the email cannot be found.
47              
48             =back
49              
50             =cut
51              
52             sub new {
53 1     1 1 19 my ($class, @args) = @_;
54 1         9 my $self = $class->next::method(@args);
55 1         13668 $self->{folder_path} = $args[0];
56 1   50     5 $self->{timeout} //= 3;
57 1         6 return $self;
58             }
59              
60             =head2 search(email => $email, subject => qr/the subject/);
61              
62             get emails with receiver address and subject(regexp). Return an array of messages which are hashref.
63              
64             my $msgs = search(email => 'hello@test.com', subject => qr/this is a subject/);
65              
66             =cut
67              
68             sub search {
69 7     7 1 6761 my ($self, %cond) = @_;
70              
71 7 100 66     85 die 'Need email address and subject regexp' unless $cond{email} && $cond{subject} && ref($cond{subject}) eq 'Regexp';
      100        
72              
73 3         9 my $email = $cond{email};
74 3         8 my $subject_regexp = $cond{subject};
75              
76 3         8 my @msgs;
77              
78 3         6 my $found = 0;
79             #mailbox maybe late, so we wait 3 seconds
80 3         13 WAIT: for (0 .. $self->{timeout}) {
81 5         1657 MSG: while (my $tmsg = $self->next_message) {
82 4         3221 $tmsg = Email::MIME->new($tmsg->as_string);
83 4         2960 my $address = $tmsg->header('To');
84 4         215 my $from = $tmsg->header('From');
85 4         186 my $subject = $tmsg->header('Subject');
86              
87 4 100 66     231 if ($address eq $email && $subject =~ $subject_regexp) {
88 3         8 my %msg;
89 3         13 $msg{body} = $tmsg->body_str;
90 3         461 $msg{address} = $address;
91 3         8 $msg{subject} = $subject;
92 3         8 $msg{from} = $from;
93 3         6 $msg{MIME} = $tmsg;
94 3         8 push @msgs, \%msg;
95 3         28 $found = 1;
96             }
97             }
98 5 100       671 last WAIT if $found;
99             # reset reader
100 3         14 $self->reset;
101 3         2999438 sleep 1;
102             }
103 3         69 return @msgs;
104             }
105              
106             =head2 reset
107              
108             Reset the mailbox
109              
110             =cut
111              
112             sub reset { ## no critic (ProhibitBuiltinHomonyms)
113 4     4 1 8 my $self = shift;
114 4         20 my $reader_class = blessed($self->{_folder});
115 4         119 delete $self->{_folder};
116 4         41 $self->{_folder} = $reader_class->new($self->{folder_path}, %$self);
117 4         71 return;
118             }
119              
120             =head2 clear
121              
122             clear the content of mailbox
123              
124             =cut
125              
126             sub clear {
127 1     1 1 1108 my $self = shift;
128 1   50     11 my $type = blessed($self->{_folder}) // '';
129              
130 1         6 $self->reset;
131              
132 1 50       5 if ($type eq 'Email::Folder::Mbox') {
133 1   50     130 truncate($self->{folder_path}, 0) // die "Cannot clear mailbox $self->{folder_path}\n";
134             } else {
135 0         0 die "Sorry, I can only clear the mailbox with the type Mbox\n";
136             }
137              
138 1         5 return 1;
139             }
140              
141             =head2 init
142              
143             init Email folder for test
144              
145             =cut
146              
147             sub init {
148 1     1 1 7 my $self = shift;
149              
150 1   50     13 my $type = blessed($self->{_folder}) // '';
151              
152 1 50       5 if ($type eq 'Email::Folder::Mbox') {
153 1   50     95 open(my $fh, ">>", $self->{folder_path}) // die "Cannot init mailbox $self->{folder_path}\n";
154 1         9 close($fh);
155             } else {
156 0         0 die "Sorry, I can only init the mailbox with the type Mbox\n";
157             }
158 1         4 return 1;
159             }
160              
161             =head1 SEE ALSO
162              
163             L
164              
165             =head1 LICENSE
166              
167             Same as perl
168              
169             =cut
170              
171             1;
172