### ----------------------------------------------------
### -- Bailador
### -- Licenses: MIT
### -- Authors: Tadeusz “tadzik” Sośnierz, Anthony Parsons, Carl Masak, Gabor Szabo, GlitchMr, Moritz Lenz, Panu Ervamaa, Paul Cochrane, Solomon Foster, Sterling Hanenkamp, Tobias Leich, ugexe, vendethiel, Martin Barth (ufobat), Emeric Fischer, Julien Simonet (jsimonet)
### -- File: t/08-OO-sessions.t
### ----------------------------------------------------
use v6.c;

use Test;

use Bailador::App;
use Bailador::RouteHelper;
use Bailador::Test;

plan 5;

class MyOwnWebApp is Bailador::App {
    submethod BUILD (|) {
        self.config.cookie-expiration = 5;
        self.add_route: make-route('GET','/setsession' => sub {
            my $session = self.session;
            $session<key> = 'value';
            "with session";
        });

        self.add_route: make-route('GET','/readsession' => sub {
            my $session = self.session;
            $session<key> || 'no value';
        });

        self.add_route: make-route('GET','/deletesession' => sub {
            self.session-delete;
            "session should be deleted";
        });
    }
}

my $app = MyOwnWebApp.new().baile('p6w');
my $first-session-id;
my $wrong-session-id;
my $second-session-id;

my $session-cookie-name;

subtest {
    plan 3;

    my %data = run-psgi-request($app, 'GET', '/setsession');
    my $response = %data<response>;
    is $response[0], 200, 'New session HTTP status 200';

    my %header = $response[1];
    ok %header<Set-Cookie>:exists, 'Session cookie available';
    my $cookie = %header<Set-Cookie>;
    my $value;
    ($session-cookie-name, $value) = $cookie.trim.split(/\s*\=\s*/, 2);
    $first-session-id = $value.split(/<[;&]>/)[0];
    is($response[2], 'with session', 'New session Content');

}, 'Set inital session';

subtest {
    plan 3;
    my %data = run-psgi-request($app, 'GET', '/readsession', headers => { cookie => "$session-cookie-name=$first-session-id" });
    my $response = %data<response>;
    is $response[0], 200, 'With session HTTP status 200';
    my %header = $response[1];

    ok %header<Set-Cookie>:exists, 'Session cookie available';
    is($response[2], 'value', 'Data from last session available');

}, 'Read session';


subtest {
    plan 3;

    $wrong-session-id = $first-session-id;
    $wrong-session-id.substr-rw(0,1) = '1';
    if $wrong-session-id eq $first-session-id {
        $wrong-session-id.substr-rw(0,1) = '2';
    }

    my %data = run-psgi-request($app, 'GET', '/readsession', headers => { cookie => "$session-cookie-name=$wrong-session-id" });
    my $response = %data<response>;
    is $response[0], 200, 'With session HTTP status 200';
    my %header = $response[1];

    ok %header<Set-Cookie>:exists, 'Session cookie available';
    is($response[2], 'no value', 'No data from last session available');

}, 'Fake session ID';

subtest {
    plan 4;
    # let the cookie expire!
    sleep 6;

    my %data = run-psgi-request($app, 'GET', '/readsession', headers => { cookie => "$session-cookie-name=$first-session-id" });
    my $response = %data<response>;
    is $response[0], 200, 'With session HTTP status 200';
    my %header = $response[1];

    ok %header<Set-Cookie>:exists, 'Session cookie available';
    is $response[2], 'no value', 'Data from last session is timed out';

    my $cookie = %header<Set-Cookie>;
    my $value;
    ($session-cookie-name, $value) = $cookie.trim.split(/\s*\=\s*/, 2);
    $second-session-id = $value.split(/<[;&]>/)[0];

    isnt $first-session-id, $second-session-id, 'got a new session ID because old session was timed out';

}, 'Session expiration';

subtest {
    plan 1;
    my %data = run-psgi-request($app, 'GET', '/deletesession', headers => { cookie => "$session-cookie-name=$second-session-id" });
    is-deeply %data<response>, [200, ["Content-Type" => "text/html"], 'session should be deleted'], 'Session deletion';
}, 'Session deletion';

done-testing;


