about summary refs log tree commit homepage
path: root/t/psgi_v2.t
diff options
context:
space:
mode:
Diffstat (limited to 't/psgi_v2.t')
-rw-r--r--t/psgi_v2.t114
1 files changed, 106 insertions, 8 deletions
diff --git a/t/psgi_v2.t b/t/psgi_v2.t
index 7d73b606..d5c328f0 100644
--- a/t/psgi_v2.t
+++ b/t/psgi_v2.t
@@ -1,18 +1,49 @@
 #!perl -w
-# Copyright (C) 2018-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 IO::Uncompress::Gunzip qw(gunzip);
 require_git(2.6);
 use PublicInbox::Eml;
 use PublicInbox::Config;
 use PublicInbox::MID qw(mids);
-require_mods(qw(DBD::SQLite Search::Xapian HTTP::Request::Common Plack::Test
+require_mods(qw(DBD::SQLite Xapian HTTP::Request::Common Plack::Test
                 URI::Escape Plack::Builder HTTP::Date));
 use_ok($_) for (qw(HTTP::Request::Common Plack::Test));
 use_ok 'PublicInbox::WWW';
 my ($tmpdir, $for_destroy) = tmpdir();
+my $enc_dup = 'ref-20150309094050.GO3427@x1.example';
+
+my $dibx = create_inbox 'v2-dup', version => 2, indexlevel => 'medium',
+                        tmpdir => "$tmpdir/dup", sub {
+        my ($im, $ibx) = @_;
+        my $common = <<"";
+Date: Mon, 9 Mar 2015 09:40:50 +0000
+From: x\@example.com
+To: y\@example.com
+Subject: re
+Message-ID: <$enc_dup>
+MIME-Version: 1.0
+
+        $im->add(PublicInbox::Eml->new($common.<<EOM)) or BAIL_OUT;
+Content-Type: text/plain; charset=utf-8
+Content-Disposition: inline
+Content-Transfer-Encoding: 8bit
+
+cr_mismatch
+pipe \x{e2}\x{94}\x{82} or not
+EOM
+        $im->add(PublicInbox::Eml->new($common.<<EOM)) or BAIL_OUT;
+Content-Type: text/plain; charset="windows-1252"
+Content-Transfer-Encoding: quoted-printable
+
+cr_mismatch\r
+pipe =E2=94=82 or not
+EOM
+};
+
 my $eml = PublicInbox::Eml->new(<<'EOF');
 From oldbug-pre-a0c07cba0e5d8b6a Fri Oct  2 00:00:00 1993
 From: a@example.com
@@ -46,6 +77,43 @@ $new_mid //= do {
         local $/;
         <$fh>;
 };
+
+my $m2t = create_inbox 'mid2tid-1', version => 2, indexlevel => 'medium', sub {
+        my ($im, $ibx) = @_;
+        for my $n (1..3) {
+                $im->add(PublicInbox::Eml->new(<<EOM)) or xbail 'add';
+Date: Fri, 02 Oct 1993 00:0$n:00 +0000
+Message-ID: <t\@$n>
+Subject: tid $n
+From: x\@example.com
+References: <a-mid\@b>
+
+$n
+EOM
+                $im->add(PublicInbox::Eml->new(<<EOM)) or xbail 'add';
+Date: Fri, 02 Oct 1993 00:0$n:00 +0000
+Message-ID: <ut\@$n>
+Subject: unrelated tid $n
+From: x\@example.com
+References: <b-mid\@b>
+
+EOM
+        }
+};
+
+my $test_lei_q_threadid = sub {
+        my ($u) = @_;
+        test_lei(sub {
+                lei_ok qw(q -f text --only), $u, qw(-T t@1 s:unrelated);
+                is $lei_out, '', 'no results on unrelated thread';
+                lei_ok qw(q -f text --only), $u, qw(-T t@1 dt:19931002000300..);
+                my @m = ($lei_out =~ m!^Message-ID: <([^>]+)>\n!gms);
+                is_deeply \@m, ['t@3'], 'got expected result from -T MSGID';
+        });
+};
+
+$test_lei_q_threadid->($m2t->{inboxdir});
+
 my $cfgpath = "$ibx->{inboxdir}/pi_config";
 {
         open my $fh, '>', $cfgpath or BAIL_OUT $!;
@@ -53,6 +121,12 @@ my $cfgpath = "$ibx->{inboxdir}/pi_config";
 [publicinbox "v2test"]
         inboxdir = $ibx->{inboxdir}
         address = $ibx->{-primary_address}
+[publicinbox "dup"]
+        inboxdir = $dibx->{inboxdir}
+        address = $dibx->{-primary_address}
+[publicinbox "m2t"]
+        inboxdir = $m2t->{inboxdir}
+        address = $m2t->{-primary_address}
 EOF
         close $fh or BAIL_OUT;
 }
@@ -145,20 +219,18 @@ my $client1 = sub {
         $cfg->each_inbox(sub { $_[0]->search->reopen });
 
         SKIP: {
-                eval { require IO::Uncompress::Gunzip };
-                skip 'IO::Uncompress::Gunzip missing', 6 if $@;
                 my ($in, $out, $status);
                 my $req = GET('/v2test/a-mid@b/raw');
                 $req->header('Accept-Encoding' => 'gzip');
                 $res = $cb->($req);
                 is($res->header('Content-Encoding'), 'gzip', 'gzip encoding');
                 $in = $res->content;
-                IO::Uncompress::Gunzip::gunzip(\$in => \$out);
+                gunzip(\$in => \$out);
                 is($out, $raw, 'gzip response matches');
 
                 $res = $cb->(GET('/v2test/a-mid@b/t.mbox.gz'));
                 $in = $res->content;
-                $status = IO::Uncompress::Gunzip::gunzip(\$in => \$out);
+                $status = gunzip(\$in => \$out);
                 unlike($out, qr/^From oldbug/sm, 'buggy "From_" line omitted');
                 like($out, qr/^hello world$/m, 'got first in t.mbox.gz');
                 like($out, qr/^hello world!$/m, 'got second in t.mbox.gz');
@@ -169,7 +241,7 @@ my $client1 = sub {
                 # search interface
                 $res = $cb->(POST('/v2test/?q=m:a-mid@b&x=m'));
                 $in = $res->content;
-                $status = IO::Uncompress::Gunzip::gunzip(\$in => \$out);
+                $status = gunzip(\$in => \$out);
                 unlike($out, qr/^From oldbug/sm, 'buggy "From_" line omitted');
                 like($out, qr/^hello world$/m, 'got first in mbox POST');
                 like($out, qr/^hello world!$/m, 'got second in mbox POST');
@@ -180,7 +252,7 @@ my $client1 = sub {
                 # all.mbox.gz interface
                 $res = $cb->(GET('/v2test/all.mbox.gz'));
                 $in = $res->content;
-                $status = IO::Uncompress::Gunzip::gunzip(\$in => \$out);
+                $status = gunzip(\$in => \$out);
                 unlike($out, qr/^From oldbug/sm, 'buggy "From_" line omitted');
                 like($out, qr/^hello world$/m, 'got first in all.mbox');
                 like($out, qr/^hello world!$/m, 'got second in all.mbox');
@@ -209,6 +281,8 @@ my $client1 = sub {
         local $SIG{__WARN__} = 'DEFAULT';
         $res = $cb->(GET('/v2test/a-mid@b/'));
         $raw = $res->content;
+        like($raw, qr/WARNING: multiple messages have this Message-ID/,
+                'warned about duplicate Message-IDs');
         like($raw, qr/^hello world$/m, 'got first message');
         like($raw, qr/^hello world!$/m, 'got second message');
         like($raw, qr/^hello ghosts$/m, 'got third message');
@@ -218,6 +292,15 @@ my $client1 = sub {
                 like($raw, qr!>\Q$mid\E</a>!s, "Message-ID $mid shown");
         }
         like($raw, qr/\b3\+ messages\b/, 'thread overview shown');
+
+        $res = $cb->(GET("/dup/$enc_dup/d/"));
+        is($res->code, 200, '/d/ (diff) endpoint works');
+        $raw = $res->content;
+        like($raw, qr!</span> cr_mismatch\n!s,
+                'cr_mismatch is only diff context');
+        like($raw, qr!>\-pipe !s, 'pipe diff del line');
+        like($raw, qr!>\+pipe !s, 'pipe diff ins line');
+        unlike $raw, qr/No newline at end of file/;
 };
 
 test_psgi(sub { $www->call(@_) }, $client1);
@@ -292,6 +375,21 @@ my $client3 = sub {
         local $SIG{__WARN__} = sub { push @warn, @_ };
         $res = $cb->(GET('/v2test/?t=1970'.'01'.'01'));
         is_deeply(\@warn, [], 'no warnings on YYYYMMDD only');
+
+        $res = $cb->(POST("/m2t/t\@1/?q=dt:19931002000300..&x=m"));
+        is($res->code, 200, 'got 200 on mid2tid query');
+        gunzip(\(my $in = $res->content) => \(my $out));
+        my @m = ($out =~ m!^Message-ID: <([^>]+)>\n!gms);
+        is_deeply(\@m, ['t@3'], 'only got latest result from query');
+
+        $res = $cb->(POST("/m2t/t\@1/?q=dt:19931002000400..&x=m"));
+        is($res->code, 404, '404 on out-of-range mid2tid query');
+
+        $res = $cb->(POST("/m2t/t\@1/?q=s:unrelated&x=m"));
+        is($res->code, 404, '404 on cross-thread search');
+
+        my $rmt = $ENV{PLACK_TEST_EXTERNALSERVER_URI};
+        $rmt and $test_lei_q_threadid->("$rmt/m2t/");
 };
 test_psgi(sub { $www->call(@_) }, $client3);
 test_httpd($env, $client3, 4);