+{
+ $rw_commit->();
+ my $res = $query->('b:hello');
+ is(scalar(@$res), 0, 'no match on body search only');
+ $res = $query->('bs:smith');
+ is(scalar(@$res), 0,
+ 'no match on body+subject search for From');
+
+ $res = $query->('q:theatre');
+ is(scalar(@$res), 1, 'only one quoted body');
+ like($res->[0]->{from_name}, qr/\AQuoter/,
+ 'got quoted body') if (scalar(@$res));
+
+ $res = $query->('nq:theatre');
+ is(scalar @$res, 1, 'only one non-quoted body');
+ like($res->[0]->{from_name}, qr/\ANon-Quoter/,
+ 'got non-quoted body') if (scalar(@$res));
+
+ foreach my $pfx (qw(b: bs:)) {
+ $res = $query->($pfx . 'theatre');
+ is(scalar @$res, 2, "searched both bodies for $pfx");
+ like($res->[0]->{from_name}, qr/\ANon-Quoter/,
+ "non-quoter first for $pfx") if scalar(@$res);
+ }
+}
+
+$ibx->with_umask(sub {
+ my $amsg = eml_load 't/search-amsg.eml';
+ my $oid = ('0'x40);
+ my $smsg = bless { blob => $oid }, 'PublicInbox::Smsg';
+ ok($rw->add_message($amsg, $smsg), 'added attachment');
+ $rw_commit->();
+ my $n = $query->('n:attached_fart.txt');
+ is(scalar @$n, 1, 'got result for n:');
+ my $res = $query->('part_deux.txt');
+ is(scalar @$res, 1, 'got result without n:');
+ is($n->[0]->{mid}, $res->[0]->{mid},
+ 'same result with and without') if scalar(@$res);
+ my $txt = $query->('"inside another"');
+ is(scalar @$txt, 1, 'found inside another');
+ is($txt->[0]->{mid}, $res->[0]->{mid},
+ 'search inside text attachments works') if scalar(@$txt);
+
+ my $art;
+ if (scalar(@$n) >= 1) {
+ my $mid = $n->[0]->{mid};
+ my ($id, $prev);
+ $art = $ibx->over->next_by_mid($mid, \$id, \$prev);
+ ok($art, 'article exists in OVER DB');
+ }
+ $rw->_msgmap_init;
+ $rw->unindex_eml($oid, $amsg);
+ $rw->commit_txn_lazy;
+ SKIP: {
+ skip('$art not defined', 1) unless defined $art;
+ is($ibx->over->get_art($art->{num}), undef,
+ 'gone from OVER DB');
+ };
+});
+
+my $all_mask = 07777;
+my $dir_mask = 02770;
+
+# FreeBSD and apparently OpenBSD does not allow non-root users to set S_ISGID,
+# so git doesn't set it, either (see DIR_HAS_BSD_GROUP_SEMANTICS in git.git)
+if ($^O =~ /(?:free|open)bsd/i) {
+ $all_mask = 0777;
+ $dir_mask = 0770;
+}
+
+foreach my $f ("$git_dir/public-inbox/msgmap.sqlite3",
+ "$git_dir/public-inbox",
+ glob("$git_dir/public-inbox/xapian*/"),
+ glob("$git_dir/public-inbox/xapian*/*")) {
+ my @st = stat($f);
+ my ($bn) = (split(m!/!, $f))[-1];
+ oct_is($st[2] & $all_mask, -f _ ? 0660 : $dir_mask,
+ "sharedRepository respected for $bn");
+}
+
+$ibx->with_umask(sub {
+ $rw_commit->();
+ my $digits = '10010260936330';
+ my $ua = 'Pine.LNX.4.10';
+ my $mid = "$ua.$digits.2460-100000\@penguin.transmeta.com";
+ is($ibx->search->mset("m:$digits")->size, 0, 'no results yet');
+ my $pine = PublicInbox::Eml->new(<<EOF);
+Subject: blah
+Message-ID: <$mid>
+From: torvalds\@transmeta
+To: list\@example.com
+
+EOF
+ my $x = $rw->add_message($pine);
+ $rw->commit_txn_lazy;
+ $ibx->search->reopen;
+ is($ibx->search->mset("m:$digits")->size, 1,
+ 'searching only digit yielded result');
+
+ my $wild = $digits;
+ for my $i (1..6) {
+ chop($wild);
+ is($ibx->search->mset("m:$wild*")->size, 1,
+ "searching chopped($i) digit yielded result $wild ");
+ }
+ is($ibx->search->mset('m:Pine m:LNX m:10010260936330')->size, 1);
+});
+
+{ # List-Id searching
+ my $found = $query->('lid:i.m.just.bored');
+ is_deeply([ filter_mids($found) ], [ 'root@s' ],
+ 'got expected mid on exact lid: search');
+
+ $found = $query->('lid:just.bored');
+ is_deeply($found, [], 'got nothing on lid: search');
+
+ $found = $query->('lid:*.just.bored');
+ is_deeply($found, [], 'got nothing on lid: search');
+
+ $found = $query->('l:i.m.just.bored');
+ is_deeply([ filter_mids($found) ], [ 'root@s' ],
+ 'probabilistic search works on full List-Id contents');
+
+ $found = $query->('l:just.bored');
+ is_deeply([ filter_mids($found) ], [ 'root@s' ],
+ 'probabilistic search works on partial List-Id contents');
+
+ $found = $query->('lid:mad');
+ is_deeply($found, [], 'no match on phrase with lid:');
+
+ $found = $query->('lid:bored');
+ is_deeply($found, [], 'no match on partial List-Id with lid:');
+
+ $found = $query->('l:nothing');
+ is_deeply($found, [], 'matched on phrase with l:');
+}
+
+$ibx->with_umask(sub {
+ $rw_commit->();
+ my $doc_id = $rw->add_message(eml_load('t/data/message_embed.eml'));
+ ok($doc_id > 0, 'messages within messages');
+ $rw->commit_txn_lazy;
+ $ibx->search->reopen;
+ my $n_test_eml = $query->('n:test.eml');
+ is(scalar(@$n_test_eml), 1, 'got a result');
+ my $n_embed2x_eml = $query->('n:embed2x.eml');
+ is_deeply($n_test_eml, $n_embed2x_eml, '.eml filenames searchable');
+ for my $m (qw(20200418222508.GA13918@dcvr 20200418222020.GA2745@dcvr
+ 20200418214114.7575-1-e@yhbt.net)) {
+ is($query->("m:$m")->[0]->{mid},
+ '20200418222508.GA13918@dcvr', 'probabilistic m:'.$m);
+ is($query->("mid:$m")->[0]->{mid},
+ '20200418222508.GA13918@dcvr', 'boolean mid:'.$m);
+ }
+ is($query->('dfpost:4dc62c50')->[0]->{mid},
+ '20200418222508.GA13918@dcvr',
+ 'diff search reaches inside message/rfc822');
+ is($query->('s:"mail header experiments"')->[0]->{mid},
+ '20200418222508.GA13918@dcvr',
+ 'Subject search reaches inside message/rfc822');
+});
+