lib/PublicInbox/TestCommon.pm | 25 ++++++++++++++++++++++++- t/filter_base.t | 12 +++++++----- t/filter_mirror.t | 9 +++++---- t/mda.t | 5 +++-- t/msg_iter.t | 10 +++++++--- t/plack.t | 20 ++++++++++++-------- t/psgi_attach.t | 13 ++++--------- t/psgi_v2.t | 5 +++-- t/search.t | 6 ++++-- diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm index b50871e8d9c65dd31105f8daa173aa020f4e8826..ac14d27bc87b9ba406edd22eb475f704a8dabc39 100644 --- a/lib/PublicInbox/TestCommon.pm +++ b/lib/PublicInbox/TestCommon.pm @@ -9,7 +9,30 @@ use Fcntl qw(FD_CLOEXEC F_SETFD F_GETFD :seek); use POSIX qw(dup2); use IO::Socket::INET; our @EXPORT = qw(tmpdir tcp_server tcp_connect require_git require_mods - run_script start_script key2sub xsys xqx); + run_script start_script key2sub xsys xqx mime_load); + +sub mime_load ($;&) { + my ($path, $cb) = @_; + if (open(my $fh, '<', $path)) { + PublicInbox::MIME->new(\(do { local $/; <$fh> })); + } elsif ($cb) { + require File::Temp; + + my $mime = $cb->(); + my ($dir) = ($path =~ m!(.+)/(?:[^/]+)\z!); + -d $dir or die "BUG: dir=$dir is not the dir of $path"; + my $fh = File::Temp->new(DIR => $dir); + $fh->autoflush(1); + print $fh $mime->as_string or die "print: $!"; + my $fn = $fh->filename; + rename($fn, $path) or die "link $fn => $path: $!"; + $fh->unlink_on_destroy(0); + pop @_; # retry via tail recursion + goto &mime_load; + } else { + die "open $path: $!"; + } +} sub tmpdir (;$) { my ($base) = @_; diff --git a/t/filter_base.t b/t/filter_base.t index f25d2dd7fb01d3271768cdaba7164344d5a3019d..7919dd65098e0309662a2f7b7fec70bc9035376f 100644 --- a/t/filter_base.t +++ b/t/filter_base.t @@ -3,7 +3,7 @@ # License: AGPL-3.0+ use strict; use warnings; use Test::More; -use Email::MIME; +use PublicInbox::TestCommon; use_ok 'PublicInbox::Filter::Base'; { @@ -21,6 +21,7 @@ } { my $f = PublicInbox::Filter::Base->new; + my $email = mime_load 't/filter_base-xhtml.eml', sub { my $html_body = "hi"; my $parts = [ Email::MIME->create( @@ -38,19 +39,20 @@ }, body => 'hi = "bye"', ) ]; - my $email = Email::MIME->create( + Email::MIME->create( header_str => [ From => 'a@example.com', Subject => 'blah', 'Content-Type' => 'multipart/alternative' ], parts => $parts, - ); + )}; # mime_load sub is($f->delivery($email), 100, "xhtml rejected"); } { my $f = PublicInbox::Filter::Base->new; + my $email = mime_load 't/filter_base-junk.eml', sub { my $parts = [ Email::MIME->create( attributes => { @@ -67,14 +69,14 @@ }, body => 'junk', ) ]; - my $email = Email::MIME->create( + Email::MIME->create( header_str => [ From => 'a@example.com', Subject => 'blah', 'Content-Type' => 'multipart/mixed' ], parts => $parts, - ); + )}; # mime_load sub is($f->delivery($email), 100, 'proprietary format rejected on glob'); } diff --git a/t/filter_mirror.t b/t/filter_mirror.t index b19461469ab6949016c3fab6c036814fb493e6eb..694209d9e07076f5e404d1ade759ccd58886f9f4 100644 --- a/t/filter_mirror.t +++ b/t/filter_mirror.t @@ -3,12 +3,13 @@ # License: AGPL-3.0+ use strict; use warnings; use Test::More; -use Email::MIME; +use PublicInbox::TestCommon; use_ok 'PublicInbox::Filter::Mirror'; my $f = PublicInbox::Filter::Mirror->new; ok($f, 'created PublicInbox::Filter::Mirror object'); { + my $email = mime_load 't/filter_mirror.eml', sub { my $html_body = "hi"; my $parts = [ Email::MIME->create( @@ -26,15 +27,15 @@ }, body => 'hi = "bye"', ) ]; - my $email = Email::MIME->create( + Email::MIME->create( header_str => [ From => 'a@example.com', Subject => 'blah', 'Content-Type' => 'multipart/alternative' ], parts => $parts, - ); + )}; # mime_laod sub is($f->ACCEPT, $f->delivery($email), 'accept any trash that comes'); } -done_testing(); + done_testing(); diff --git a/t/mda.t b/t/mda.t index fb505146f8feb080db191dfaad9e2f334e0d2957..5457f17f3cde72e2186f48c079715564114a3bb6 100644 --- a/t/mda.t +++ b/t/mda.t @@ -233,6 +233,7 @@ ok(run_script(['-learn', 'ham'], undef, { 0 => \$in }), "learned ham idempotently "); # ensure trained email is filtered, too + $mime = mime_load 't/mda-mime.eml', sub { my $html_body = "hi"; my $parts = [ Email::MIME->create( @@ -251,7 +252,7 @@ body => 'hi = "bye"', ) ]; $mid = 'multipart-html-sucks@11'; - $mime = Email::MIME->create( + Email::MIME->create( header_str => [ From => 'a@example.com', Subject => 'blah', @@ -260,7 +261,7 @@ 'Message-ID' => "<$mid>", 'Content-Type' => 'multipart/alternative', ], parts => $parts, - ); + )}; # mime_load sub { $in = $mime->as_string; diff --git a/t/msg_iter.t b/t/msg_iter.t index 573ee41209ba86742145c9d74244e3822dcab60e..ac2066a2780d8d4fd7acb09a242633ae1863a183 100644 --- a/t/msg_iter.t +++ b/t/msg_iter.t @@ -3,16 +3,18 @@ # License: AGPL-3.0+ use strict; use warnings; use Test::More; -use Email::MIME; +use PublicInbox::TestCommon; use PublicInbox::Hval qw(ascii_html); use PublicInbox::InboxWritable; use_ok('PublicInbox::MsgIter'); { + my $mime = mime_load 't/msg_iter-order.eml', sub { my $parts = [ Email::MIME->create(body => "a\n"), Email::MIME->create(body => "b\n") ]; - my $mime = Email::MIME->create(parts => $parts, + Email::MIME->create(parts => $parts, header_str => [ From => 'root@localhost' ]); + }; # mime_load sub my @parts; msg_iter($mime, sub { my ($part, $level, @ex) = @{$_[0]}; @@ -24,13 +26,15 @@ is_deeply(\@parts, [ [ qw(a 1 1) ], [ qw(b 1 2) ] ], 'order is fine'); } { + my $mime = mime_load 't/msg_iter-nested.eml', sub { my $parts = [ Email::MIME->create(body => 'a'), Email::MIME->create(body => 'b') ]; $parts = [ Email::MIME->create(parts => $parts, header_str => [ From => 'sub@localhost' ]), Email::MIME->create(body => 'sig') ]; - my $mime = Email::MIME->create(parts => $parts, + Email::MIME->create(parts => $parts, header_str => [ From => 'root@localhost' ]); + }; # mime_load sub my @parts; msg_iter($mime, sub { my ($part, $level, @ex) = @{$_[0]}; diff --git a/t/plack.t b/t/plack.t index b16bc8de9cd2bbae4d5c73cbcd9d77c98c694fbe..d45dbcd2085b2a286625a43299fd7ff359d4f87b 100644 --- a/t/plack.t +++ b/t/plack.t @@ -52,11 +52,12 @@ chomp @ls; # multipart with two text bodies my %attr_text = (attributes => { content_type => 'text/plain' }); + $mime = mime_load 't/plack-2-txt-bodies.eml', sub { my $parts = [ Email::MIME->create(%attr_text, body => 'hi'), Email::MIME->create(%attr_text, body => 'bye') ]; - $mime = Email::MIME->create( + Email::MIME->create( header_str => [ From => 'a@example.com', Subject => 'blargh', @@ -64,11 +65,13 @@ 'Message-ID' => '', 'In-Reply-To' => '' ], parts => $parts, - ); + )}; # mime_load sub $im->add($mime); # multipart with attached patch + filename - $parts = [ Email::MIME->create(%attr_text, body => 'hi, see attached'), + $mime = mime_load 't/plack-attached-patch.eml', sub { + my $parts = [ + Email::MIME->create(%attr_text, body => 'hi, see attached'), Email::MIME->create( attributes => { content_type => 'text/plain', @@ -78,18 +81,19 @@ body => "--- a/file\n+++ b/file\n" . "@@ -49, 7 +49,34 @@\n" ) ]; - $mime = Email::MIME->create( + Email::MIME->create( header_str => [ From => 'a@example.com', Subject => '[PATCH] asdf', 'Message-ID' => '' ], parts => $parts - ); + )}; # mime_load sub $im->add($mime); # multipart collapsed to single quoted-printable text/plain - $parts = [ + $mime = mime_load 't/plack-qp.eml', sub { + my $parts = [ Email::MIME->create( attributes => { content_type => 'text/plain', @@ -98,14 +102,14 @@ }, body => 'hi = bye', ) ]; - $mime = Email::MIME->create( + Email::MIME->create( header_str => [ From => 'qp@example.com', Subject => 'QP', 'Message-ID' => '', ], parts => $parts, - ); + )}; like($mime->body_raw, qr/hi =3D bye=/, 'our test used QP correctly'); $im->add($mime); diff --git a/t/psgi_attach.t b/t/psgi_attach.t index 2376bba7bf2f042e099588da5499429cd679193d..0dde9323dc3943a265284be192abf63022caa48b 100644 --- a/t/psgi_attach.t +++ b/t/psgi_attach.t @@ -26,13 +26,11 @@ my $im = PublicInbox::Import->new($git, 'test', $addr); $im->init_bare; { - open my $fh, '<', '/dev/urandom' or die "unable to open urandom: $!\n"; - sysread($fh, my $buf, 8); - is(8, length($buf), 'read some random data'); my $qp = "abcdef=g\n==blah\n"; - my $b64 = 'b64'.$buf."\n"; + my $b64 = "b64\xde\xad\xbe\xef\n"; my $txt = "plain\ntext\npass\nthrough\n"; my $dot = "dotfile\n"; + my $mime = mime_load 't/psgi_attach.eml', sub { my $parts = [ Email::MIME->create( attributes => { @@ -61,14 +59,11 @@ content_type => 'text/plain', }, body => $dot), ]; - my $mime = Email::MIME->create( + Email::MIME->create( parts => $parts, header_str => [ From => 'root@z', 'Message-Id' => '', Subject => 'hi'] - ); - $mime = $mime->as_string; - $mime =~ s/\r\n/\n/g; # normalize to LF only - $mime = PublicInbox::MIME->new($mime); + )}; # mime_load sub $im->add($mime); $im->done; diff --git a/t/psgi_v2.t b/t/psgi_v2.t index bc26a1129364b0543c1e2995c170405a36d53755..5d212ca6f7ca1bb126bef8f92d02123f01789891 100644 --- a/t/psgi_v2.t +++ b/t/psgi_v2.t @@ -225,6 +225,7 @@ is($res->code, 404, 'v2 git URL w/o shard fails'); # ensure conflicted attachments can be resolved foreach my $body (qw(old new)) { + $mime = mime_load "t/psgi_v2-$body.eml", sub { my $parts = [ Email::MIME->create( attributes => { content_type => 'text/plain' }, @@ -238,12 +239,12 @@ }, body => $body ) ]; - $mime = Email::MIME->create( + Email::MIME->create( parts => $parts, header_str => [ From => 'root@z', 'Message-ID' => '', Subject => 'hi'] - ); + )}; # mime_load sub ok($im->add($mime), "added attachment $body"); } $im->done; diff --git a/t/search.t b/t/search.t index 0fd5fdeede0c6521d45cf2af2fad92fd5f3a3f98..0301fd90b6289f379063400ac888343f7ed9d433 100644 --- a/t/search.t +++ b/t/search.t @@ -371,6 +371,7 @@ } } $ibx->with_umask(sub { + my $amsg = mime_load 't/search-amsg.eml', sub { my $part1 = Email::MIME->create( attributes => { content_type => 'text/plain', @@ -391,7 +392,7 @@ filename => 'part_deux.txt', }, body_str => 'inside another', ); - my $amsg = Email::MIME->create( + Email::MIME->create( header_str => [ Subject => 'see attachment', 'Message-ID' => '', @@ -399,7 +400,8 @@ From => 'John Smith ', To => 'list@example.com', ], parts => [ $part1, $part2 ], - ); + )}; # mime_load sub + ok($rw->add_message($amsg), 'added attachment'); $rw_commit->(); $ro->reopen;