user/dev discussion of public-inbox itself
 help / color / Atom feed
From: Eric Wong <e@yhbt.net>
To: meta@public-inbox.org
Subject: [PATCH 10/22] t/plack.t: modernize and unindent
Date: Sat, 25 Jan 2020 04:44:58 +0000
Message-ID: <20200125044510.13769-11-e@yhbt.net> (raw)
In-Reply-To: <20200125044510.13769-1-e@yhbt.net>

This test will be expanded, and we can take advantage of
run_script to simplify our internal API use.
---
 t/plack.t | 393 ++++++++++++++++++++++++++----------------------------
 1 file changed, 191 insertions(+), 202 deletions(-)

diff --git a/t/plack.t b/t/plack.t
index ec45b02c..443831a1 100644
--- a/t/plack.t
+++ b/t/plack.t
@@ -8,7 +8,7 @@ use PublicInbox::TestCommon;
 my $psgi = "./examples/public-inbox.psgi";
 my ($tmpdir, $for_destroy) = tmpdir();
 my $pi_config = "$tmpdir/config";
-my $maindir = "$tmpdir/main.git";
+my $inboxdir = "$tmpdir/main.git";
 my $addr = 'test-public@example.com';
 my @mods = qw(HTTP::Request::Common Plack::Test URI::Escape);
 require_mods(@mods);
@@ -17,25 +17,22 @@ use_ok 'PublicInbox::Git';
 my @ls;
 
 foreach my $mod (@mods) { use_ok $mod; }
+local $ENV{PI_CONFIG} = $pi_config;
+ok(-f $psgi, "psgi example file found");
+my $pfx = 'http://example.com/test';
+ok(run_script(['-init', 'test', $inboxdir, "$pfx/", $addr]),
+	'initialized repo');
+PublicInbox::Import::run_die([qw(git config -f), $pi_config,
+	'publicinbox.test.newsgroup', 'inbox.test']);
+open my $fh, '>', "$inboxdir/description" or die "open: $!\n";
+print $fh "test for public-inbox\n";
+close $fh or die "close: $!\n";
+my $app = require $psgi;
+my $git = PublicInbox::Git->new($inboxdir);
+my $im = PublicInbox::Import->new($git, 'test', $addr);
+# ensure successful message delivery
 {
-	ok(-f $psgi, "psgi example file found");
-	is(0, system(qw(git init -q --bare), $maindir), "git init (main)");
-	open my $fh, '>', "$maindir/description" or die "open: $!\n";
-	print $fh "test for public-inbox\n";
-	close $fh or die "close: $!\n";
-	open $fh, '>>', $pi_config or die;
-	print $fh <<EOF or die;
-[publicinbox "test"]
-	address = $addr
-	inboxdir = $maindir
-	url = http://example.com/test/
-	newsgroup = inbox.test
-EOF
-	close $fh or die;
-
-	# ensure successful message delivery
-	{
-		my $mime = Email::MIME->new(<<EOF);
+	my $mime = Email::MIME->new(<<EOF);
 From: Me <me\@example.com>
 To: You <you\@example.com>
 Cc: $addr
@@ -45,210 +42,202 @@ Date: Fri, 02 Oct 1993 00:00:00 +0000
 
 zzzzzz
 EOF
-		my $git = PublicInbox::Git->new($maindir);
-		my $im = PublicInbox::Import->new($git, 'test', $addr);
-		$im->add($mime);
-		$im->done;
-		my $rev = $git->qx(qw(rev-list HEAD));
-		like($rev, qr/\A[a-f0-9]{40}/, "good revision committed");
-		@ls = $git->qx(qw(ls-tree -r --name-only HEAD));
-		chomp @ls;
-	}
-	my $app = eval {
-		local $ENV{PI_CONFIG} = $pi_config;
-		require $psgi;
-	};
-
-	test_psgi($app, sub {
-		my ($cb) = @_;
-		foreach my $u (qw(robots.txt favicon.ico .well-known/foo)) {
-			my $res = $cb->(GET("http://example.com/$u"));
-			is($res->code, 404, "$u is missing");
-		}
-	});
-
-	# redirect with newsgroup
-	test_psgi($app, sub {
-		my ($cb) = @_;
-		my $from = 'http://example.com/inbox.test';
-		my $to = 'http://example.com/test/';
-		my $res = $cb->(GET($from));
-		is($res->code, 301, 'newsgroup name is permanent redirect');
-		is($to, $res->header('Location'), 'redirect location matches');
-		$from .= '/';
-		is($res->code, 301, 'newsgroup name/ is permanent redirect');
-		is($to, $res->header('Location'), 'redirect location matches');
-	});
-
-	# redirect with trailing /
-	test_psgi($app, sub {
-		my ($cb) = @_;
-		my $from = 'http://example.com/test';
-		my $to = "$from/";
-		my $res = $cb->(GET($from));
-		is(301, $res->code, 'is permanent redirect');
-		is($to, $res->header('Location'),
-			'redirect location matches with trailing slash');
-	});
+	$im->add($mime);
+	$im->done;
+	my $rev = $git->qx(qw(rev-list HEAD));
+	like($rev, qr/\A[a-f0-9]{40}/, "good revision committed");
+	@ls = $git->qx(qw(ls-tree -r --name-only HEAD));
+	chomp @ls;
+}
 
-	my $pfx = 'http://example.com/test';
-	foreach my $t (qw(t T)) {
-		test_psgi($app, sub {
-			my ($cb) = @_;
-			my $u = $pfx . "/blah\@example.com/$t";
-			my $res = $cb->(GET($u));
-			is(301, $res->code, "redirect for missing /");
-			my $location = $res->header('Location');
-			like($location, qr!/\Q$t\E/#u\z!,
-				'redirected with missing /');
-		});
-	}
-	foreach my $t (qw(f)) {
-		test_psgi($app, sub {
-			my ($cb) = @_;
-			my $u = $pfx . "/blah\@example.com/$t";
-			my $res = $cb->(GET($u));
-			is(301, $res->code, "redirect for legacy /f");
-			my $location = $res->header('Location');
-			like($location, qr!/blah\@example\.com/\z!,
-				'redirected with missing /');
-		});
+test_psgi($app, sub {
+	my ($cb) = @_;
+	foreach my $u (qw(robots.txt favicon.ico .well-known/foo)) {
+		my $res = $cb->(GET("http://example.com/$u"));
+		is($res->code, 404, "$u is missing");
 	}
-
-	test_psgi($app, sub {
-		my ($cb) = @_;
-		my $atomurl = 'http://example.com/test/new.atom';
-		my $res = $cb->(GET('http://example.com/test/new.html'));
-		is(200, $res->code, 'success response received');
-		like($res->content, qr!href="new\.atom"!,
-			'atom URL generated');
-		like($res->content, qr!href="blah\@example\.com/"!,
-			'index generated');
-		like($res->content, qr!1993-10-02!, 'date set');
-	});
-
+});
+
+# redirect with newsgroup
+test_psgi($app, sub {
+	my ($cb) = @_;
+	my $from = 'http://example.com/inbox.test';
+	my $to = 'http://example.com/test/';
+	my $res = $cb->(GET($from));
+	is($res->code, 301, 'newsgroup name is permanent redirect');
+	is($to, $res->header('Location'), 'redirect location matches');
+	$from .= '/';
+	is($res->code, 301, 'newsgroup name/ is permanent redirect');
+	is($to, $res->header('Location'), 'redirect location matches');
+});
+
+# redirect with trailing /
+test_psgi($app, sub {
+	my ($cb) = @_;
+	my $from = 'http://example.com/test';
+	my $to = "$from/";
+	my $res = $cb->(GET($from));
+	is(301, $res->code, 'is permanent redirect');
+	is($to, $res->header('Location'),
+		'redirect location matches with trailing slash');
+});
+
+foreach my $t (qw(t T)) {
 	test_psgi($app, sub {
 		my ($cb) = @_;
-		my $res = $cb->(GET($pfx . '/atom.xml'));
-		is(200, $res->code, 'success response received for atom');
-		my $body = $res->content;
-		like($body, qr!link\s+href="\Q$pfx\E/blah\@example\.com/"!s,
-			'atom feed generated correct URL');
-		like($body, qr/<title>test for public-inbox/,
-			"set title in XML feed");
-		like($body, qr/zzzzzz/, 'body included');
+		my $u = $pfx . "/blah\@example.com/$t";
+		my $res = $cb->(GET($u));
+		is(301, $res->code, "redirect for missing /");
+		my $location = $res->header('Location');
+		like($location, qr!/\Q$t\E/#u\z!,
+			'redirected with missing /');
 	});
-
+}
+foreach my $t (qw(f)) {
 	test_psgi($app, sub {
 		my ($cb) = @_;
-		my $path = '/blah@example.com/';
-		my $res = $cb->(GET($pfx . $path));
-		is(200, $res->code, "success for $path");
-		like($res->content, qr!<title>hihi - Me</title>!,
-			"HTML returned");
-
-		$path .= 'f/';
-		$res = $cb->(GET($pfx . $path));
-		is(301, $res->code, "redirect for $path");
+		my $u = $pfx . "/blah\@example.com/$t";
+		my $res = $cb->(GET($u));
+		is(301, $res->code, "redirect for legacy /f");
 		my $location = $res->header('Location');
 		like($location, qr!/blah\@example\.com/\z!,
-			'/$MESSAGE_ID/f/ redirected to /$MESSAGE_ID/');
-	});
-
-	test_psgi($app, sub {
-		my ($cb) = @_;
-		my $res = $cb->(GET($pfx . '/blah@example.com/raw'));
-		is(200, $res->code, 'success response received for /*/raw');
-		like($res->content, qr!^From !sm, "mbox returned");
+			'redirected with missing /');
 	});
+}
 
-	# legacy redirects
-	foreach my $t (qw(m f)) {
-		test_psgi($app, sub {
-			my ($cb) = @_;
-			my $res = $cb->(GET($pfx . "/$t/blah\@example.com.txt"));
-			is(301, $res->code, "redirect for old $t .txt link");
-			my $location = $res->header('Location');
-			like($location, qr!/blah\@example\.com/raw\z!,
-				".txt redirected to /raw");
-		});
-	}
-
-	my %umap = (
-		'm' => '',
-		'f' => '',
-		't' => 't/',
-	);
-	while (my ($t, $e) = each %umap) {
-		test_psgi($app, sub {
-			my ($cb) = @_;
-			my $res = $cb->(GET($pfx . "/$t/blah\@example.com.html"));
-			is(301, $res->code, "redirect for old $t .html link");
-			my $location = $res->header('Location');
-			like($location,
-				qr!/blah\@example\.com/$e(?:#u)?\z!,
-				".html redirected to new location");
-		});
-	}
-	foreach my $sfx (qw(mbox mbox.gz)) {
-		test_psgi($app, sub {
-			my ($cb) = @_;
-			my $res = $cb->(GET($pfx . "/t/blah\@example.com.$sfx"));
-			is(301, $res->code, 'redirect for old thread link');
-			my $location = $res->header('Location');
-			like($location,
-			     qr!/blah\@example\.com/t\.mbox(?:\.gz)?\z!,
-			     "$sfx redirected to /mbox.gz");
-		});
-	}
+test_psgi($app, sub {
+	my ($cb) = @_;
+	my $atomurl = 'http://example.com/test/new.atom';
+	my $res = $cb->(GET('http://example.com/test/new.html'));
+	is(200, $res->code, 'success response received');
+	like($res->content, qr!href="new\.atom"!,
+		'atom URL generated');
+	like($res->content, qr!href="blah\@example\.com/"!,
+		'index generated');
+	like($res->content, qr!1993-10-02!, 'date set');
+});
+
+test_psgi($app, sub {
+	my ($cb) = @_;
+	my $res = $cb->(GET($pfx . '/atom.xml'));
+	is(200, $res->code, 'success response received for atom');
+	my $body = $res->content;
+	like($body, qr!link\s+href="\Q$pfx\E/blah\@example\.com/"!s,
+		'atom feed generated correct URL');
+	like($body, qr/<title>test for public-inbox/,
+		"set title in XML feed");
+	like($body, qr/zzzzzz/, 'body included');
+});
+
+test_psgi($app, sub {
+	my ($cb) = @_;
+	my $path = '/blah@example.com/';
+	my $res = $cb->(GET($pfx . $path));
+	is(200, $res->code, "success for $path");
+	like($res->content, qr!<title>hihi - Me</title>!,
+		"HTML returned");
+
+	$path .= 'f/';
+	$res = $cb->(GET($pfx . $path));
+	is(301, $res->code, "redirect for $path");
+	my $location = $res->header('Location');
+	like($location, qr!/blah\@example\.com/\z!,
+		'/$MESSAGE_ID/f/ redirected to /$MESSAGE_ID/');
+});
+
+test_psgi($app, sub {
+	my ($cb) = @_;
+	my $res = $cb->(GET($pfx . '/blah@example.com/raw'));
+	is(200, $res->code, 'success response received for /*/raw');
+	like($res->content, qr!^From !sm, "mbox returned");
+});
+
+# legacy redirects
+foreach my $t (qw(m f)) {
 	test_psgi($app, sub {
 		my ($cb) = @_;
-		# for a while, we used to support /$INBOX/$X40/
-		# when we "compressed" long Message-IDs to SHA-1
-		# Now we're stuck supporting them forever :<
-		foreach my $path (@ls) {
-			$path =~ tr!/!!d;
-			my $from = "http://example.com/test/$path/";
-			my $res = $cb->(GET($from));
-			is(301, $res->code, 'is permanent redirect');
-			like($res->header('Location'),
-				qr!/test/blah\@example\.com/!,
-				'redirect from x40 MIDs works');
-		}
+		my $res = $cb->(GET($pfx . "/$t/blah\@example.com.txt"));
+		is(301, $res->code, "redirect for old $t .txt link");
+		my $location = $res->header('Location');
+		like($location, qr!/blah\@example\.com/raw\z!,
+			".txt redirected to /raw");
 	});
+}
 
-	# dumb HTTP clone/fetch support
+my %umap = (
+	'm' => '',
+	'f' => '',
+	't' => 't/',
+);
+while (my ($t, $e) = each %umap) {
 	test_psgi($app, sub {
 		my ($cb) = @_;
-		my $path = '/test/info/refs';
-		my $req = HTTP::Request->new('GET' => $path);
-		my $res = $cb->($req);
-		is(200, $res->code, 'refs readable');
-		my $orig = $res->content;
-
-		$req->header('Range', 'bytes=5-10');
-		$res = $cb->($req);
-		is(206, $res->code, 'got partial response');
-		is($res->content, substr($orig, 5, 6), 'partial body OK');
-
-		$req->header('Range', 'bytes=5-');
-		$res = $cb->($req);
-		is(206, $res->code, 'got partial another response');
-		is($res->content, substr($orig, 5), 'partial body OK past end');
+		my $res = $cb->(GET($pfx . "/$t/blah\@example.com.html"));
+		is(301, $res->code, "redirect for old $t .html link");
+		my $location = $res->header('Location');
+		like($location,
+			qr!/blah\@example\.com/$e(?:#u)?\z!,
+			".html redirected to new location");
 	});
-
-	# things which should fail
+}
+foreach my $sfx (qw(mbox mbox.gz)) {
 	test_psgi($app, sub {
 		my ($cb) = @_;
-
-		my $res = $cb->(PUT('/'));
-		is(405, $res->code, 'no PUT to / allowed');
-		$res = $cb->(PUT('/test/'));
-		is(405, $res->code, 'no PUT /$INBOX allowed');
-
-		# TODO
-		# $res = $cb->(GET('/'));
+		my $res = $cb->(GET($pfx . "/t/blah\@example.com.$sfx"));
+		is(301, $res->code, 'redirect for old thread link');
+		my $location = $res->header('Location');
+		like($location,
+		     qr!/blah\@example\.com/t\.mbox(?:\.gz)?\z!,
+		     "$sfx redirected to /mbox.gz");
 	});
 }
+test_psgi($app, sub {
+	my ($cb) = @_;
+	# for a while, we used to support /$INBOX/$X40/
+	# when we "compressed" long Message-IDs to SHA-1
+	# Now we're stuck supporting them forever :<
+	foreach my $path (@ls) {
+		$path =~ tr!/!!d;
+		my $from = "http://example.com/test/$path/";
+		my $res = $cb->(GET($from));
+		is(301, $res->code, 'is permanent redirect');
+		like($res->header('Location'),
+			qr!/test/blah\@example\.com/!,
+			'redirect from x40 MIDs works');
+	}
+});
+
+# dumb HTTP clone/fetch support
+test_psgi($app, sub {
+	my ($cb) = @_;
+	my $path = '/test/info/refs';
+	my $req = HTTP::Request->new('GET' => $path);
+	my $res = $cb->($req);
+	is(200, $res->code, 'refs readable');
+	my $orig = $res->content;
+
+	$req->header('Range', 'bytes=5-10');
+	$res = $cb->($req);
+	is(206, $res->code, 'got partial response');
+	is($res->content, substr($orig, 5, 6), 'partial body OK');
+
+	$req->header('Range', 'bytes=5-');
+	$res = $cb->($req);
+	is(206, $res->code, 'got partial another response');
+	is($res->content, substr($orig, 5), 'partial body OK past end');
+});
+
+# things which should fail
+test_psgi($app, sub {
+	my ($cb) = @_;
+
+	my $res = $cb->(PUT('/'));
+	is(405, $res->code, 'no PUT to / allowed');
+	$res = $cb->(PUT('/test/'));
+	is(405, $res->code, 'no PUT /$INBOX allowed');
+
+	# TODO
+	# $res = $cb->(GET('/'));
+});
 
 done_testing();

  parent reply index

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-25  4:44 [PATCH 00/22] HTML display cleanups, fixes, speedups Eric Wong
2020-01-25  4:44 ` [PATCH 01/22] www*stream: favor \&close instead of *close Eric Wong
2020-01-25  4:44 ` [PATCH 02/22] www: use "skel" terminology consistently Eric Wong
2020-01-25  4:44 ` [PATCH 03/22] view: improve readability around walk_thread Eric Wong
2020-01-25  4:44 ` [PATCH 04/22] searchview: keep $noop sub private to the package Eric Wong
2020-01-25  4:44 ` [PATCH 05/22] view: reduce parameters for html_footer Eric Wong
2020-01-25  4:44 ` [PATCH 06/22] view: thread_skel: drop constant tpfx parameter Eric Wong
2020-01-25  4:44 ` [PATCH 07/22] view: simplify duplicate Message-ID handling Eric Wong
2020-01-25  4:44 ` [PATCH 08/22] wwwstream: discard single-use $ctx fields after use Eric Wong
2020-01-25  4:44 ` [PATCH 09/22] view: start performing buffering into {obuf} Eric Wong
2020-01-25  4:44 ` Eric Wong [this message]
2020-01-25  4:44 ` [PATCH 11/22] init: use Import::run_die instead of system() Eric Wong
2020-01-25  4:45 ` [PATCH 12/22] tests: move the majority of t/view.t into t/plack.t Eric Wong
2020-01-25  4:45 ` [PATCH 13/22] xt/perf-msgview: switch to multipart_text_as_html Eric Wong
2020-01-25  4:45 ` [PATCH 14/22] view: inline and eliminate msg_html Eric Wong
2020-01-25  4:45 ` [PATCH 15/22] linkify: compile $LINK_RE once Eric Wong
2020-01-25  4:45 ` [PATCH 16/22] linkify: move to_html over from ViewDiff Eric Wong
2020-01-25  4:45 ` [PATCH 17/22] searchidx: skip filenames on "diff --git ..." Eric Wong
2020-01-25  4:45 ` [PATCH 18/22] searchidx: don't assume "a/" and "b/" as prefixes Eric Wong
2020-01-25  4:45 ` [PATCH 19/22] viewdiff: add "b=" param with non-standard diff prefix Eric Wong
2020-01-25  4:45 ` [PATCH 20/22] viewdiff: add "b=" param when missing "diff --git" line Eric Wong
2020-01-25  4:45 ` [PATCH 21/22] viewdiff: use autovivification for long_path hash Eric Wong
2020-01-25  4:45 ` [PATCH 22/22] viewdiff: rewrite and simplify Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200125044510.13769-11-e@yhbt.net \
    --to=e@yhbt.net \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

user/dev discussion of public-inbox itself

Archives are clonable:
	git clone --mirror https://public-inbox.org/meta
	git clone --mirror http://czquwvybam4bgbro.onion/meta
	git clone --mirror http://hjrcffqmbrq6wope.onion/meta
	git clone --mirror http://ou63pmih66umazou.onion/meta

Example config snippet for mirrors

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.mail.public-inbox.meta
	nntp://ou63pmih66umazou.onion/inbox.comp.mail.public-inbox.meta
	nntp://czquwvybam4bgbro.onion/inbox.comp.mail.public-inbox.meta
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.mail.public-inbox.meta
	nntp://news.gmane.io/gmane.mail.public-inbox.general

 note: .onion URLs require Tor: https://www.torproject.org/

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git