summaryrefslogtreecommitdiff
path: root/t/tests/success-failure.t
blob: 5a1a99901368f387ca3b0c45d2e38dc3fce512c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!perl 
use strict;
use warnings;
 
use IO::Async::PSGI;
 
use IO::Async::Loop;
use IO::Async::Test;
use HTTP::Request;
use HTTP::Message::PSGI;
use HTTP::Exception;
 
use Test2::Bundle::Extended;
use Data::Printer;
 
my $loop = IO::Async::Loop->new;
testing_loop $loop;
 
my $app_f = sub {
    my $f = $_[0]->{'io.async.loop'}
        ->delay_future(after=>0.2);
 
    if ($_[0]->{PATH_INFO} =~ /fail/) {
        return $f->then_fail("Expected failure\n");
    }
 
    if ($_[0]->{PATH_INFO} =~ /exc/) {
        return $f->then_fail(
            HTTP::Exception::401->throw(
                status_message => 'Expected failure',
            ),
        );
    }
 
    return $f->then_done([200,[],['coderef']]);
};
 
my $psgi = IO::Async::PSGI->new({
    app => $app_f,
});
my $app = $psgi->psgi_app;
 
my $success = [200,[],['coderef']];
my $fail_500 = [ 500, array { etc; }, [ "Expected failure\n" ] ];
my $fail_401 = [ 401, array { etc; }, [ 'Expected failure' ] ];
 
my %cases = (
    success => $success,
    '/success' => $success,
    fail => $fail_500,
    '/fail' => $fail_500,
    exception => $fail_401,
    '/exception' => $fail_401,
);
 
sub run_test {
    my ($use_loop) = @_;
 
    for my $c (sort keys %cases) {
        subtest $c => sub {
            my $req = HTTP::Request->new(
                GET => "http://localhost/$c",
            )->to_psgi;
 
            $req->{'io.async.loop'}=$loop
                if $use_loop;
 
            my $raw_res = $app->($req);
            my $res;
            ref_ok(
                $raw_res,
                'CODE',
                'got a delayed response',
            );
 
            $raw_res->(sub{$res=shift});
 
            wait_for { $res } if $use_loop;
 
            is(
                $res,
                $cases{$c},
                'correct response',
                np $res,
            );
        }
    }
}
 
subtest 'with loop' => sub { run_test(1) };
subtest 'without loop' => sub { run_test(0) };
 
package My::PSGI {
    use Moo;
    extends 'IO::Async::PSGI';
 
    sub on_app_failure {
        my ($self,$env,$exc,@details) = @_;
 
        if ($exc =~ /^Expected/) {
            return [ 501, [], ['something special from '.$env->{REQUEST_URI}] ];
        }
        return $self->next::method($env,$exc,@details);
    }
};
 
for my $fail (qw(my/fail /my/fail /my//fail exception /exception)) {
    $cases{$fail} = [501, [], ["something special from /$fail"] ];
}
delete @cases{qw(fail /fail)};
$psgi = My::PSGI->new({app=>$app_f});
$app = $psgi->psgi_app;
 
subtest 'custom failure handler' => sub { run_test(1) };
 
done_testing;