| 12
 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
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 
 | use Test::More import => ['!pass'];
use strict;
use warnings;
BEGIN {
    use Dancer::ModuleLoader;
    plan skip_all => "skip test with Test::TCP in win32" if $^O eq 'MSWin32';
    plan skip_all => 'Test::TCP is needed to run this test'
        unless Dancer::ModuleLoader->load('Test::TCP' => "1.30");
    plan skip_all => 'YAML is needed to run this test'
        unless Dancer::ModuleLoader->load('YAML');
    plan skip_all => "File::Temp 0.22 required"
        unless Dancer::ModuleLoader->load( 'File::Temp', '0.22' );
}
use HTTP::Tiny::NoProxy;
use HTTP::CookieJar;
use File::Spec;
my $tempdir = File::Temp::tempdir(CLEANUP => 1, TMPDIR => 1);
use Dancer;
use Dancer::Logger;
 
my @clients = qw(one two three);
my @engines = qw(Simple YAML);
if ($ENV{DANCER_TEST_COOKIE}) {
    push @engines, "cookie";
    setting(session_cookie_key => "secret/foo*@!");
}
# Support testing with Dancer::Session::DBI if explictly told to by being
# provided with DB connection details via env vars (the appropriate table would
# have to have been created, too)
if ($ENV{DANCER_TEST_SESSION_DBI_DSN}) {
    push @engines, "DBI";
    setting(
        session_options => {
            dsn      => $ENV{DANCER_TEST_SESSION_DBI_DSN},
            user     => $ENV{DANCER_TEST_SESSION_DBI_USER},
            password => $ENV{DANCER_TEST_SESSION_DBI_PASS},
            table    => $ENV{DANCER_TEST_SESSION_DBI_TABLE},
        }
    );
}
# Support testing with Dancer::Session::Storable if explicitly told to
# (non-core module, so not tested by default; if you want to run these
# tests against it, make sure it's installed first)
if ($ENV{DANCER_TEST_SESSION_STORABLE}) {
    push @engines, "Storable";
}
plan tests => 13 * scalar(@clients) * scalar(@engines) + (scalar(@engines));
foreach my $engine (@engines) {
Test::TCP::test_tcp(
    client => sub {
        my $port = shift;
        foreach my $client (@clients) {
            my $ua = HTTP::Tiny::NoProxy->new(cookie_jar => HTTP::CookieJar->new);
            my $res = $ua->get("http://127.0.0.1:$port/read_session");
            like $res->{content}, qr/name=''/, 
            "empty session for client $client";
            $res = $ua->get("http://127.0.0.1:$port/set_session/$client");
            ok($res->{success}, "set_session for client $client");
            $res = $ua->get("http://127.0.0.1:$port/read_session");
            like $res->{content}, qr/name='$client'/,
            "session looks good for client $client";
            $res = $ua->get("http://127.0.0.1:$port/session/after_hook/read");
            ok($res->{success}, "Reading a session var in after hook worked");
            is(
                $res->{content},
                "Read value set in route",
                "Session var read in after hook and returned",
            );
            $res = $ua->get("http://127.0.0.1:$port/session/after_hook/write");
            ok($res->{success}, "writing a session var in after hook worked");
            is(
                $res->{content},
                "Read value changed in hook",
                "Session var set changed in hook successfully",
            );
            # Now read once more, to make sure that the session var set in the
            # after hook in the last test was actually persisted:
            $res = $ua->get("http://127.0.0.1:$port/session/after_hook");
            ok($res->{success}, "Fetched the session var");
            is(
                $res->{content},
                "value changed in hook",
                "Session var set in hook persisted",
            );
            $res = $ua->get("http://127.0.0.1:$port/session/after_hook/send_file");
            ok(
                $res->{success},
                "after hook accessing session after send_file doesn't explode"
                . " (GH #1205)",
            );
            is(
                $res->{content},
                "Hi there, random person (after hook fired)",
                "send_file route sent expected content and no explosion",
            );
            # Now destroy the session (e.g. logging out)
            $res = $ua->get("http://127.0.0.1:$port/session/destroy");
            ok(
                $res->{success},
                "called session destroy route",
            );
            # ... and the previous session has indeed gone
            $res = $ua->get("http://127.0.0.1:$port/read_session");
            like $res->{content}, qr/name=''/, 
            "empty session for client $client after destroy";
        }
    },
    server => sub {
        my $port = shift;
        use File::Spec;
        use lib File::Spec->catdir( 't', 'lib' );
        use TestApp;
        Dancer::Config->load;
        setting appdir => $tempdir;
        Dancer::Logger->init('File');
        ok(setting(session => $engine), "using engine $engine");
        setting(log => "debug");
        setting(logger => "console");
        set( show_errors  => 1,
             startup_info => 0,
             environment  => 'production',
             port         => $port,
             server       => '127.0.0.1' );
        Dancer->dance();
    },
);
}
 |