diff options
Diffstat (limited to 't/lei-import.t')
-rw-r--r-- | t/lei-import.t | 124 |
1 files changed, 120 insertions, 4 deletions
diff --git a/t/lei-import.t b/t/lei-import.t index 6e9a853c..89eb1492 100644 --- a/t/lei-import.t +++ b/t/lei-import.t @@ -1,14 +1,17 @@ #!perl -w -# Copyright (C) 2020-2021 all contributors <meta@public-inbox.org> +# Copyright (C) all contributors <meta@public-inbox.org> # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt> -use strict; use v5.10.1; use PublicInbox::TestCommon; +use v5.12; use PublicInbox::TestCommon; +use PublicInbox::DS qw(now); +use PublicInbox::IO qw(write_file); +use autodie qw(open close truncate); test_lei(sub { ok(!lei(qw(import -F bogus), 't/plack-qp.eml'), 'fails with bogus format'); like($lei_err, qr/\bis `eml', not --in-format/, 'gave error message'); lei_ok(qw(q s:boolean), \'search miss before import'); unlike($lei_out, qr/boolean/i, 'no results, yet'); -open my $fh, '<', 't/data/0001.patch' or BAIL_OUT $!; +open my $fh, '<', 't/data/0001.patch'; lei_ok([qw(import -F eml -)], undef, { %$lei_opt, 0 => $fh }, \'import single file from stdin') or diag $lei_err; close $fh; @@ -18,7 +21,7 @@ lei_ok(qw(q s:boolean -f mboxrd), \'blob accessible after import'); my $expect = [ eml_load('t/data/0001.patch') ]; require PublicInbox::MboxReader; my @cmp; - open my $fh, '<', \$lei_out or BAIL_OUT "open :scalar: $!"; + open my $fh, '<', \$lei_out; PublicInbox::MboxReader->mboxrd($fh, sub { my ($eml) = @_; $eml->header_set('Status'); @@ -110,6 +113,119 @@ $res = json_utf8->decode($lei_out); is_deeply($res->[0]->{kw}, ['seen'], 'keyword set'); is_deeply($res->[0]->{L}, ['inbox'], 'label set'); +# idempotent import can add label +lei_ok([qw(import -F eml - +L:boombox)], + undef, { %$lei_opt, 0 => \$eml_str }); +lei_ok(qw(q m:inbox@example.com)); +$res = json_utf8->decode($lei_out); +is_deeply($res->[0]->{kw}, ['seen'], 'keyword remains set'); +is_deeply($res->[0]->{L}, [qw(boombox inbox)], 'new label added'); + +# idempotent import can add keyword +lei_ok([qw(import -F eml - +kw:answered)], + undef, { %$lei_opt, 0 => \$eml_str }); +lei_ok(qw(q m:inbox@example.com)); +$res = json_utf8->decode($lei_out); +is_deeply($res->[0]->{kw}, [qw(answered seen)], 'keyword added'); +is_deeply($res->[0]->{L}, [qw(boombox inbox)], 'labels preserved'); + +# +kw:seen is not a location +open my $null, '<', '/dev/null'; +ok(!lei([qw(import -F eml +kw:seen)], undef, { %$lei_opt, 0 => $null }), + 'import fails w/ only kw arg'); +like($lei_err, qr/\bLOCATION\.\.\. or --stdin must be set/s, 'error message'); + +lei_ok([qw(import -F eml +kw:flagged)], # no lone dash (`-') + undef, { %$lei_opt, 0 => \$eml_str }, + 'import succeeds with implicit --stdin'); +lei_ok(qw(q m:inbox@example.com)); +$res = json_utf8->decode($lei_out); +is_deeply($res->[0]->{kw}, [qw(answered flagged seen)], 'keyword added'); +is_deeply($res->[0]->{L}, [qw(boombox inbox)], 'labels preserved'); + +lei_ok qw(import --commit-delay=1 +L:bin -F eml t/data/binary.patch); +lei_ok 'ls-label'; +unlike($lei_out, qr/\bbin\b/, 'commit-delay delays label'); +my $end = now + 10; +my $n = 1; +diag 'waiting for lei/store commit...'; +do { + tick $n; + $n = 0.1; +} until (!lei('ls-label') || $lei_out =~ /\bbin\b/ || now > $end); +like($lei_out, qr/\bbin\b/, 'commit-delay eventually commits'); + +SKIP: { + my $strace = strace_inject(1); # skips if strace is old or non-Linux + my $tmpdir = tmpdir; + my $tr = "$tmpdir/tr"; + my $cmd = [ $strace, '-q', "-o$tr", '-f', + "-P", File::Spec->rel2abs('t/plack-qp.eml'), + '-e', 'inject=readv,read:error=EIO']; + lei_ok qw(daemon-pid); + chomp(my $daemon_pid = $lei_out); + push @$cmd, '-p', $daemon_pid; + require PublicInbox::Spawn; + require PublicInbox::AutoReap; + my $pid = PublicInbox::Spawn::spawn($cmd, \%ENV); + my $ar = PublicInbox::AutoReap->new($pid); + tick; # wait for strace to attach + ok(!lei(qw(import -F eml t/plack-qp.eml)), + '-F eml import fails on pathname error injection'); + my $IO = '[Ii](?:nput)?/[Oo](?:utput)?'; + like($lei_err, qr!error reading t/plack-qp\.eml: .*?$IO error!, + 'EIO noted in stderr'); + open $fh, '<', 't/plack-qp.eml'; + ok(!lei(qw(import -F eml -), undef, { %$lei_opt, 0 => $fh }), + '-F eml import fails on stdin error injection'); + like($lei_err, qr!error reading .*?: .*?$IO error!, + 'EIO noted in stderr'); +} + +{ + local $ENV{PI_CONFIG} = "$ENV{HOME}/pi_config"; + write_file '>', $ENV{PI_CONFIG}, <<EOM; +[publicinboxImport] + dropUniqueUnsubscribe +EOM + my $in = <<EOM; +List-Unsubscribe: <https://example.com/some-UUID-here/test> +List-Unsubscribe-Post: List-Unsubscribe=One-Click +Message-ID: <unsubscribe-1\@example> +Subject: unsubscribe-1 example +From: u\@example.com +To: 2\@example.com +Date: Fri, 02 Oct 1993 00:00:00 +0000 + +EOM + lei_ok [qw(import -F eml +L:unsub)], undef, { %$lei_opt, 0 => \$in }, + 'import succeeds w/ List-Unsubscribe'; + lei_ok qw(q L:unsub -f mboxrd); + like $lei_out, qr/some-UUID-here/, + 'Unsubscribe header preserved despite PI_CONFIG dropping'; + lei_ok qw(q L:unsub -o), "v2:$ENV{HOME}/v2-1"; + lei_ok qw(q s:unsubscribe -f mboxrd --only), "$ENV{HOME}/v2-1"; + unlike $lei_out, qr/some-UUID-here/, + 'Unsubscribe header dropped w/ dropUniqueUnsubscribe'; + like $lei_out, qr/Message-ID: <unsubscribe-1\@example>/, + 'wrote expected message to v2 output'; + + # the default for compatibility: + truncate $ENV{PI_CONFIG}, 0; + lei_ok qw(q L:unsub -o), "v2:$ENV{HOME}/v2-2"; + lei_ok qw(q s:unsubscribe -f mboxrd --only), "$ENV{HOME}/v2-2"; + like $lei_out, qr/some-UUID-here/, + 'Unsubscribe header preserved by default :<'; + + # ensure we can fail + write_file '>', $ENV{PI_CONFIG}, <<EOM; +[publicinboxImport] + dropUniqueUnsubscribe = bogus +EOM + ok(!lei(qw(q L:unsub -o), "v2:$ENV{HOME}/v2-3"), 'bad config fails'); + like $lei_err, qr/is not boolean/, 'non-booleaness noted in stderr'; + ok !-d "$ENV{HOME}/v2-3", 'v2 directory not created'; +} # see t/lei_to_mail.t for "import -F mbox*" }); |