+
+ $res = $cb->(GET('/test/'));
+ $html = $res->content;
+ like($html, qr/\bhref="no-subject-at-all[^>]+>\(no subject\)</,
+ 'subject-less message linked from "/$INBOX/"');
+ like($html, qr/\bhref="blank-subject[^>]+>\(no subject\)</,
+ 'blank subject message linked from "/$INBOX/"');
+ like($html, qr/test Ævar/,
+ "displayed Ævar's name properly in topic view");
+
+ $res = $cb->(GET('/test/?q=tc:git'));
+ like($html, qr/\bhref="no-subject-at-all[^>]+>\(no subject\)</,
+ 'subject-less message linked from "/$INBOX/?q=..."');
+ like($html, qr/\bhref="blank-subject[^>]+>\(no subject\)</,
+ 'blank subject message linked from "/$INBOX/?q=..."');
+ $res = $cb->(GET('/test/no-subject-at-all@example.com/raw'));
+ like($res->header('Content-Disposition'),
+ qr/filename=no-subject\.txt/);
+ $res = $cb->(GET('/test/no-subject-at-all@example.com/t.mbox.gz'));
+ like($res->header('Content-Disposition'),
+ qr/filename=no-subject\.mbox\.gz/);
+
+ # "full threads" mbox.gz download
+ $res = $cb->(POST('/test/?q=s:test&x=m&t'));
+ is($res->code, 200, 'successful mbox download with threads');
+ gunzip(\($res->content) => \(my $before));
+ is_deeply([ "Message-ID: <$mid>\n", "Message-ID: <reply\@asdf>\n" ],
+ [ grep(/^Message-ID:/m, split(/^/m, $before)) ],
+ 'got full thread');
+
+ # clobber has_threadid to emulate old versions:
+ {
+ my $sidx = PublicInbox::SearchIdx->new($ibx, 0);
+ my $xdb = $sidx->idx_acquire;
+ $xdb->set_metadata('has_threadid', '0');
+ $sidx->idx_release;
+ }
+ $config->each_inbox(sub { delete $_[0]->{search} });
+ $res = $cb->(GET('/test/?q=s:test'));
+ is($res->code, 200, 'successful search w/o has_threadid');
+ unlike($html, qr/download mbox\.gz: .*?"full threads"/s,
+ '"full threads" download option not shown w/o has_threadid');
+
+ # in case somebody uses curl to bypass <form>
+ $res = $cb->(POST('/test/?q=s:test&x=m&t'));
+ is($res->code, 200, 'successful mbox download w/ threads');
+ gunzip(\($res->content) => \(my $after));
+ isnt($before, $after);