### ----------------------------------------------------
### -- HTTP::UserAgent
### -- Licenses: MIT
### -- Authors: Filip Sergot
### -- File: t/030-cookies.rakutest
### ----------------------------------------------------
use Test;
use HTTP::Cookies;
# strangely these aren't required for the test to work

plan 31;

BEGIN my $file = $*PROGRAM.sibling('cookies.dat').absolute;
LEAVE try $file.IO.unlink;

my $c = HTTP::Cookies.new(
    file     => $file,
);

# new
ok $c, 'new 1/3';
is $c.file, $file, 'new 2/3';
is $c.autosave, 0, 'new 3/3';

# set-cookie
$c.set-cookie(
    'Set-Cookie: name1=value1; expires=DATE; Path=/; Domain=gugle.com; Secure; HttpOnly'
);
my $c1 = $c.cookies[0];
ok $c1, 'set-cookie 1/11';
is $c1.name, 'name1', 'set-cookie 2/11';
is $c1.value, 'value1', 'set-cookie 3/11';
is $c1.fields.elems, 0, 'set-cookie 4/11';
is $c1.secure, 'Secure', 'set-cookie 5/11';
is $c1.httponly, 'HttpOnly', 'set-cookie 6/11';

$c.set-cookie(
    'Set-Cookie: name2=value2; expires=DATE2; Path=/path; Domain=gugle.com;'
);
my $c2 = $c.cookies[1];
ok $c2, 'set-cookie 7/11';
is $c2.name, 'name2', 'set-cookie 8/11';
is $c2.value, 'value2', 'set-cookie 9/11';
is $c2.fields.elems, 0, 'set-cookie 10/11';
ok !$c2.secure, 'set-cookie 11/11';

# Str
my $result = "Set-Cookie: name1=value1; expires=DATE; Path=/; Domain=gugle.com; Secure; HttpOnly\nSet-Cookie: name2=value2; expires=DATE2; Path=/path; Domain=gugle.com";

my token set_cookie {
   ^^ Set\-Cookie\:\s+
}

my token name_1 { name1\=value1\;\s+ }
my token expires_1 { :i expires\=DATE }
my token path_1 { :i Path\=\/ }
my token domain_1 { :i Domain\=gugle\.com }
my token secure_1 { Secure }
my token http_only_1 { HttpOnly }
my token fields_1 {
                     [    <expires_1> 
                       |  <path_1>
                       |  <domain_1>
                       |  <secure_1>
                       |  <http_only_1>
                     ] * % '; '

}

my token cookie_1 { 
                     <set_cookie>
                     <name_1>
                     <fields_1>
                     $$
}


my token name_2 { name2\=value2\;\s+ }

my token expires_2 { :i expires\=DATE2 } 
my token path_2 { :i Path\=\/path } 
my token domain_2 { :i Domain\=gugle\.com }

my token fields_2 {
   [  
         <expires_2>
      |  <path_2>
      |  <domain_2>
   ] * % '; '
}


my token cookie_2 { 
                     <set_cookie>
                     <name_2> 
                     <fields_2>
                     $$
}


my rule cookies { 
                   <cookie_1>
                   <cookie_2>
}

like $c.Str, /^<cookies>$/, "Str 1/6";
like $c.Str, /<expires_1>/, "Str 2/6"; 
like $c.Str, /<path_1>/, "Str 3/6";
like $c.Str, /<domain_1>/, "Str 4/6";
like $c.Str, /<secure_1>/, "Str 5/6";
like $c.Str, /<http_only_1>/, "Str 6/6";



# save
my $file_header = "#LWP6-Cookies-0.1\n";
my $elems_before_save = $c.cookies.elems;
$c.save;

my token file_header { ^^ '#'LWP6\-Cookies\-0\.1 $$ }

my rule cookie_file {
   <file_header>
   <cookies>

}

like $c.file.IO.slurp, /<cookie_file>/, 'save 1/1';

# clear
$c.clear;
ok !$c.cookies, 'clear 1/1';

# load
$c.load;

is $c.cookies.elems, $elems_before_save, "Same number of cookies";
#like $c.Str, /^<cookies>$/, "load 1/1";

$c = HTTP::Cookies.new(
    file     => $file,
    autosave => 1,
);
$c.load;

# add-cookie-header
$c.set-cookie(
    'Set-Cookie: namek=songo; expires=DATE2; Domain=gugyl.com;'
);

my $req = HTTP::Request.new(GET => 'http://gugyl.com');
$c.add-cookie-header($req);
# Domain restriction
is $req.field('Cookie').values.elems, 1, 'add-cookie-header 1/?';

$c.set-cookie(
    'Set-Cookie: name3=value3; expires=DATE2; Path=/;'
);
$req = HTTP::Request.new(GET => 'http://gugle.com');
$c.add-cookie-header($req);
# 'Domain'less cookies
#
# TODO:
#is $req.field('Cookie').values.elems, 2, 'add-cookie-header 2/3';

$req = HTTP::Request.new(GET => 'http://gugle.com/path');
$c.add-cookie-header($req);
# Path restriction
#
# TODO:
#is $req.field('Cookie').values.elems, 1, 'add-cookie-header 3/3';

# extract-cookkies
subtest {
my $resp = HTTP::Response.new(200);
$resp.field(Set-Cookie => 'k=v');
$c.extract-cookies($resp);
is $c.cookies.elems, 5, 'extract-cookies 1/1';
}, "extract-cookies 1/1";

# clear-expired
$c.set-cookie('Set-Cookie: n1=v1; Expires=Sun, 06 Nov 1994 08:49:37 GMT');
ok $c.clear-expired, 'clear-expired 1/3';
is $c.cookies.elems, 5, 'clear-expired 2/3';
ok ! $c.cookies.grep({ .name eq 'n1' }), 'clear-expired 3/3';

# autosave
$c.clear;
is $c.cookies.elems, 0, 'autosave 1/1';

subtest {

    lives-ok {
        my $c = HTTP::Cookies.new; 
        lives-ok { $c.set-cookie('Set-Cookie: mykey=myvalue;'); }, "set cookie with mykey=myvalue";
        is $c.cookies.elems, 1, "got one cookie";
        is $c.cookies[0].name, "mykey", "got the expected name";
        is $c.cookies[0].value, "myvalue", "got the expected value";
    }, "no hyphen in either key or value";

    lives-ok {
        my $c = HTTP::Cookies.new; 
        lives-ok { $c.set-cookie('Set-Cookie: mykey=my-value;'); }, "set cookie with mykey=my-value";
        is $c.cookies.elems, 1, "got one cookie";
        is $c.cookies[0].name, "mykey", "got the expected name";
        is $c.cookies[0].value, "my-value", "got the expected value";
    }, "hyphen in value";

    lives-ok {
        my $c = HTTP::Cookies.new; 
        lives-ok { $c.set-cookie('Set-Cookie: my-key=myvalue;'); }, "set cookie with my-key=myvalue";
        is $c.cookies.elems, 1, "got one cookie";
        is $c.cookies[0].name, "my-key", "got the expected name";
        is $c.cookies[0].value, "myvalue", "got the expected value";
    }, "hyphen in name";

    lives-ok {
        my $c = HTTP::Cookies.new; 
        lives-ok { $c.set-cookie('Set-Cookie: my-key=my-value;'); }, "set cookie with my-key=my-value";
        is $c.cookies.elems, 1, "got one cookie";
        is $c.cookies[0].name, "my-key", "got the expected name";
        is $c.cookies[0].value, "my-value", "got the expected value";
    }, "hyphen in name and value";

}, "issue #154";

subtest {
    my $c = HTTP::Cookies.new; 
    lives-ok { $c.set-cookie('Set-Cookie: icwp-app-flash=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/'); }, "set cookie with representative values";
    is $c.cookies.elems, 1, "got one cookies";
    is $c.cookies[0].name, "icwp-app-flash", "got right name";
    is $c.cookies[0].value, "deleted", "and the right value";
    is $c.cookies[0].fields.elems, 1, "and got the one field that was expected";
    is $c.cookies[0].fields<Max-Age>,0, "and the field is correct";
}, "issue #163";

# vim: expandtab shiftwidth=4


