about summary refs log tree commit homepage
path: root/t
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-08-13 02:32:22 +0000
committerEric Wong <e@80x24.org>2015-08-13 03:30:40 +0000
commit675494c58ef7a39a92c79cbf02975b9da3991c0b (patch)
tree5ab166b191b8bec3e112977b86ae7806ef1952d6 /t
parent2981d6929f400630e575bcc8fc1851bc531e73e9 (diff)
downloadpublic-inbox-675494c58ef7a39a92c79cbf02975b9da3991c0b.tar.gz
This shall allow us to search for replies/threads more easily.
Diffstat (limited to 't')
-rw-r--r--t/search.t240
1 files changed, 240 insertions, 0 deletions
diff --git a/t/search.t b/t/search.t
new file mode 100644
index 00000000..201578d4
--- /dev/null
+++ b/t/search.t
@@ -0,0 +1,240 @@
+# Copyright (C) 2015, all contributors <meta@public-inbox.org>
+# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+use strict;
+use warnings;
+use Test::More;
+use File::Temp qw/tempdir/;
+use PublicInbox::Search;
+use Email::MIME;
+use Data::Dumper;
+my $tmpdir = tempdir(CLEANUP => 1);
+my $git_dir = "$tmpdir/a.git";
+my ($root_id, $last_id);
+
+is(0, system(qw(git init -q --bare), $git_dir), "git init (main)");
+eval { PublicInbox::Search->new($git_dir) };
+ok($@, "exception raised on non-existent DB");
+
+my $rw = PublicInbox::Search->new($git_dir, 1);
+my $ro = PublicInbox::Search->new($git_dir);
+
+{
+        my $root = Email::MIME->create(
+                header_str => [
+                        Date => 'Fri, 02 Oct 1993 00:00:00 +0000',
+                        Subject => 'hello world',
+                        'Message-ID' => '<root@s>',
+                        From => 'John Smith <js@example.com>',
+                        To => 'list@example.com',
+                ],
+                body => "\\m/\n");
+        my $last = Email::MIME->create(
+                header_str => [
+                        Date => 'Sat, 02 Oct 2010 00:00:00 +0000',
+                        Subject => 'Re: hello world',
+                        'In-Reply-To' => '<root@s>',
+                        'Message-ID' => '<last@s>',
+                        From => 'John Smith <js@example.com>',
+                        To => 'list@example.com',
+                ],
+                body => "goodbye forever :<\n");
+
+        my $rv;
+        $root_id = $rw->add_message($root);
+        is($root_id, int($root_id), "root_id is an integer: $root_id");
+        $last_id = $rw->add_message($last);
+        is($last_id, int($last_id), "last_id is an integer: $last_id");
+}
+
+sub filter_mids {
+        my ($res) = @_;
+        sort(map { (split(/\n/, $_))[0] } @{$res->{msgs}});
+}
+
+{
+        $ro->reopen;
+        my $found = $ro->lookup_message('<root@s>');
+        ok($found, "message found");
+        is($root_id, $found->{doc_id}, 'doc_id set correctly');
+        $found->ensure_metadata;
+        is($found->mid, 'root@s', 'mid set correctly');
+        ok(int($found->thread_id) > 0, 'thread_id is an integer');
+
+        my @exp = sort qw(root@s last@s);
+        my $res = $ro->query("path:hello_world");
+        my @res = filter_mids($res);
+        is_deeply(\@res, \@exp, 'got expected results for path: match');
+
+        foreach my $p (qw(hello hello_ hello_world2 hello_world_)) {
+                $res = $ro->query("path:$p");
+                is($res->{count}, 0, "path variant `$p' does not match");
+        }
+
+        $res = $ro->query('subject:(hello world)');
+        @res = filter_mids($res);
+        is_deeply(\@res, \@exp, 'got expected results for subject:() match');
+
+        $res = $ro->query('subject:"hello world"');
+        @res = filter_mids($res);
+        is_deeply(\@res, \@exp, 'got expected results for subject:"" match');
+
+        $res = $ro->query('subject:"hello world"', {limit => 1});
+        is(scalar @{$res->{msgs}}, 1, "limit works");
+        my $first = $res->{msgs}->[0];
+
+        $res = $ro->query('subject:"hello world"', {offset => 1});
+        is(scalar @{$res->{msgs}}, 1, "offset works");
+        my $second = $res->{msgs}->[0];
+
+        isnt($first, $second, "offset returned different result from limit");
+
+        foreach my $f (qw(inreplyto references)) {
+                $res = $ro->query($f . ':root@s');
+                @res = filter_mids($res);
+                is_deeply(\@res, [ 'last@s' ],
+                          "got expected results for $f: match");
+                $res = $ro->query($f . ':root');
+                is($res->{count}, 0, "no partial mid match");
+        }
+}
+
+# ghost vivication
+{
+        $rw->reopen;
+        my $rmid = '<ghost-message@s>';
+        my $reply_to_ghost = Email::MIME->create(
+                header_str => [
+                        Date => 'Sat, 02 Oct 2010 00:00:00 +0000',
+                        Subject => 'Re: ghosts',
+                        'Message-ID' => '<ghost-reply@s>',
+                        'In-Reply-To' => $rmid,
+                        From => 'Time Traveler <tt@example.com>',
+                        To => 'list@example.com',
+                ],
+                body => "-_-\n");
+
+        my $rv;
+        my $reply_id = $rw->add_message($reply_to_ghost);
+        is($reply_id, int($reply_id), "reply_id is an integer: $reply_id");
+
+        my $was_ghost = Email::MIME->create(
+                header_str => [
+                        Date => 'Sat, 02 Oct 2010 00:00:01 +0000',
+                        Subject => 'ghosts',
+                        'Message-ID' => $rmid,
+                        From => 'Laggy Sender <lag@example.com>',
+                        To => 'list@example.com',
+                ],
+                body => "are real\n");
+
+        my $ghost_id = $rw->add_message($was_ghost);
+        is($ghost_id, int($ghost_id), "ghost_id is an integer: $ghost_id");
+        ok($ghost_id < $reply_id, "ghost vivified from earlier message");
+}
+
+# search thread on ghost
+{
+        $ro->reopen;
+
+        # Subject:
+        my $res = $ro->query('ghost');
+        my @exp = sort qw(ghost-message@s ghost-reply@s);
+        my @res = filter_mids($res);
+        is_deeply(\@res, \@exp, 'got expected results for Subject match');
+
+        # body
+        $res = $ro->query('goodbye');
+        is((split(/\n/, $res->{msgs}->[0]))[0], 'last@s',
+           'got goodbye message body');
+}
+
+# long message-id
+{
+        $rw->reopen;
+        $ro->reopen;
+        my $long_mid = 'last' . ('x' x 60). '@s';
+        my $long_midc = Digest::SHA::sha1_hex($long_mid);
+
+        my $long = Email::MIME->create(
+                header_str => [
+                        Date => 'Sat, 02 Oct 2010 00:00:00 +0000',
+                        Subject => 'long message ID',
+                        'References' => '<root@s> <last@s>',
+                        'In-Reply-To' => '<last@s>',
+                        'Message-ID' => "<$long_mid>",
+                        From => '"Long I.D." <long-id@example.com>',
+                        To => 'list@example.com',
+                ],
+                body => "wut\n");
+        my $long_id = $rw->add_message($long);
+        is($long_id, int($long_id), "long_id is an integer: $long_id");
+
+        $ro->reopen;
+        my $res = $ro->query('references:root@s');
+        my @res = filter_mids($res);
+        is_deeply(\@res, [ sort('last@s', $long_midc) ],
+                  "got expected results for references: match");
+
+        my $replies = $ro->get_replies('root@s');
+        $replies = [ filter_mids($replies) ];
+        is_deeply($replies, [ filter_mids($res) ], "get_replies matches");
+
+        my $long_reply_mid = 'reply-to-long@1';
+        my $long_reply = Email::MIME->create(
+                header_str => [
+                        Subject => 'I break references',
+                        Date => 'Sat, 02 Oct 2010 00:00:00 +0000',
+                        'Message-ID' => "<$long_reply_mid>",
+                        # No References:
+                        # 'References' => '<root@s> <last@s> <'.$long_mid.'>',
+                        'In-Reply-To' => "<$long_mid>",
+                        From => '"no1 <no1@example.com>',
+                        To => 'list@example.com',
+                ],
+                body => "no References\n");
+        ok($rw->add_message($long_reply) > $long_id, "inserted long reply");
+
+        $ro->reopen;
+        my $t = $ro->get_thread('root@s');
+        is($t->{count}, 4, "got all 4 mesages in thread");
+        my @exp = sort($long_reply_mid, 'root@s', 'last@s', $long_midc);
+        @res = filter_mids($t);
+        is_deeply(\@res, \@exp, "get_thread works");
+}
+
+# quote prioritization
+{
+        $rw->reopen;
+        $rw->add_message(Email::MIME->create(
+                header_str => [
+                        Date => 'Sat, 02 Oct 2010 00:00:01 +0000',
+                        Subject => 'hello',
+                        'Message-ID' => '<quote@a>',
+                        From => 'Quoter <quoter@example.com>',
+                        To => 'list@example.com',
+                ],
+                body => "> theatre illusions\nfade\n"));
+
+        $rw->add_message(Email::MIME->create(
+                header_str => [
+                        Date => 'Sat, 02 Oct 2010 00:00:02 +0000',
+                        Subject => 'hello',
+                        'Message-ID' => '<nquote@a>',
+                        From => 'Non-Quoter<non-quoter@example.com>',
+                        To => 'list@example.com',
+                ],
+                body => "theatre\nfade\n"));
+        my $res = $rw->query("theatre");
+        is($res->{count}, 2, "got both matches");
+        like($res->{msgs}->[0], qr/\Anquote\@a/, "non-quoted scores higher");
+        like($res->{msgs}->[1], qr/\Aquote\@a/, "quoted result still returned");
+
+        $res = $rw->query("illusions");
+        is($res->{count}, 1, "got a match for quoted text");
+        like($res->{msgs}->[0], qr/\Aquote\@a/,
+                "quoted result returned if nothing else");
+}
+
+done_testing();
+
+1;