#!perl
my
$t
= Pinto::Tester->new;
my
%opts
= (
root
=>
$t
->pinto->root );
my
$app
= Pinto::Server->new(
%opts
)->to_app;
my
@headers
= (
Accept
=>
$PINTO_PROTOCOL_ACCEPT
);
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$req
= GET(
'modules/02packages.details.txt.gz'
);
my
$res
=
$cb
->(
$req
);
is
$res
->code, 200,
'Correct status code'
;
is
$res
->header(
'Content-Type'
),
'application/x-gzip'
,
'Correct Type header'
;
cmp_ok
$res
->header(
'Content-Length'
),
'>'
, 4000,
'Reasonable Length header'
;
cmp_ok
$res
->header(
'Content-Length'
),
'<'
, 7000,
'Reasonable Length header'
;
is
$res
->header(
'Content-Length'
),
length
$res
->content,
'Length header matches actual length'
;
is
$res
->header(
'Cache-Control'
),
'no-cache'
,
'Got a "Cache-Control: no-cache" header'
;
isnt str2time(
$res
->header(
'Last-Modified'
) ),
undef
,
'Last-Modified header contains a proper HTTP::Date string'
;
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
@paths
=
qw(authors/01mailrc.txt.gz modules/03modlist.data.gz)
;
for
my
$path
(
@paths
) {
for
my
$prefix
(
'stacks/master/'
,
''
) {
my
$url
=
$prefix
.
$path
;
my
$req
= GET(
$url
);
my
$res
=
$cb
->(
$req
);
is
$res
->code, 200,
"Got response for $url"
;
is
$res
->header(
'Cache-Control'
),
"no-cache"
,
"$url got a 'Cache-Control: no-cache' header"
;
}
}
};
subtest
'validate archive'
=>
sub
{
my
$archive
= make_dist_archive(
'TestDist-1.0=Foo~0.7; Bar~0.8'
)->stringify;
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$params
= {
author
=>
'THEBARD'
,
recurse
=> 0,
message
=>
'test'
,
archives
=> [
$archive
] };
my
$req
= POST(
'action/add'
,
@headers
,
Content
=> {
action
=> encode_json(
$params
) } );
my
$res
=
$cb
->(
$req
);
action_response_ok(
$res
);
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$params
= {
stack
=>
'master'
};
my
$req
= POST(
'action/lock'
,
@headers
,
Content
=> {
action
=> encode_json(
$params
) } );
my
$res
=
$cb
->(
$req
);
action_response_ok(
$res
);
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$params
= {
author
=>
'THEBARD'
,
recurse
=> 0,
message
=>
'test'
,
archives
=> [
$archive
] };
my
$req
= POST(
'action/add'
,
@headers
,
Content
=> {
action
=> encode_json(
$params
) } );
my
$res
=
$cb
->(
$req
);
action_response_not_ok(
$res
,
qr{is locked}
);
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$url
=
'stacks/master/authors/id/T/TH/THEBARD/TestDist-1.0.tar.gz'
;
my
$req
= GET(
$url
);
my
$res
=
$cb
->(
$req
);
is
$res
->code, 200,
"Correct status code for GET $url"
;
is
$res
->header(
'Content-Type'
),
'application/x-gzip'
,
"Correct Type header for GET $url"
;
is
$res
->header(
'Content-Length'
), -s
$archive
,
"Length header matches actual archive size for GET $url"
;
is
$res
->header(
'Content-Length'
),
length
$res
->content,
"Length header matches actual content length for GET $url"
;
};
my
$last_modified
;
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$url
=
'stacks/master/authors/id/T/TH/THEBARD/TestDist-1.0.tar.gz'
;
my
$req
= HEAD(
$url
);
my
$res
=
$cb
->(
$req
);
$last_modified
=
$res
->header(
'Last-Modified'
);
isnt str2time(
$last_modified
),
undef
,
"Last-Modified header contains a proper HTTP::Date string for HEAD $url"
;
is
$res
->code, 200,
"Correct status code for HEAD $url"
;
is
$res
->header(
'Content-Type'
),
'application/x-gzip'
,
"Correct Type header for HEAD $url"
;
is
$res
->header(
'Content-Length'
), -s
$archive
,
"Length header matches actual archive size for HEAD $url"
;
is
length
$res
->content, 0,
"No content returned for HEAD $url"
;
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$url
=
'stacks/master/authors/id/T/TH/THEBARD/TestDist-1.0.tar.gz'
;
my
$req
= GET(
$url
,
'If-Modified-Since'
=>
$last_modified
);
my
$res
=
$cb
->(
$req
);
is
$res
->code, 304,
"Correct status code for unmodified $url"
;
is
$res
->header(
'Content-Type'
),
undef
,
"No Content-Type header for 304 response"
;
is
$res
->header(
'Content-Length'
),
undef
,
"No Content-Length header for 304 response"
;
is
length
$res
->content, 0,
"No content returned for 304 response"
;
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$params
= {};
my
$req
= POST(
'action/list'
,
@headers
,
Content
=> {
action_args
=> encode_json(
$params
) } );
my
$res
=
$cb
->(
$req
);
is
$res
->code, 200,
'Correct status code'
;
like
$res
->content,
qr{\s Foo \s+ 0.7 \s+ \S+ \n}
mx,
'Listing contains the Foo package'
;
like
$res
->content,
qr{\s Bar \s+ 0.8 \s+ \S+ \n}
mx,
'Listing contains the Bar package'
;
};
};
for
my
$v
( 1, 2 ) {
my
$stack
=
"stack_$v"
;
my
$archive
= make_dist_archive(
"Fruit-$v=Apple~$v; Orange~$v"
)->stringify;
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$params
= {
stack
=>
$stack
};
my
$req
= POST(
'action/new'
,
@headers
,
Content
=> {
action
=> encode_json(
$params
) } );
my
$res
=
$cb
->(
$req
);
action_response_ok(
$res
);
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$params
= {
author
=>
'JOHN'
,
recurse
=> 0,
stack
=>
$stack
,
message
=>
'test'
,
archives
=> [
$archive
] };
my
$req
= POST(
'action/add'
,
@headers
,
Content
=> {
action
=> encode_json(
$params
) } );
my
$res
=
$cb
->(
$req
);
action_response_ok(
$res
);
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$req
= GET(
"stacks/$stack/modules/02packages.details.txt.gz"
);
my
$res
=
$cb
->(
$req
);
is
$res
->code, 200,
'Correct status code'
;
my
$temp
= File::Temp->new;
print
{
$temp
}
$res
->content;
close
$temp
;
my
$fh
= IO::Zlib->new(
$temp
->filename,
"rb"
) or
die
$!;
my
$index
=
join
''
, <
$fh
>;
close
$fh
;
for
(
qw(Apple Orange)
) {
like
$index
,
qr{^ $_ \s+ $v \s+ J/JO/JOHN/Fruit-$v.tar.gz $}
mx,
"index contains package $_-$v"
;
}
};
}
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$req
= GET(
'bogus/path'
);
my
$res
=
$cb
->(
$req
);
is
$res
->code, 404,
'Correct status code'
;
is
$res
->header(
'Content-Type'
),
'text/plain'
;
is
$res
->header(
'Content-Length'
),
length
$res
->content;
like
$res
->content,
qr{not found}
i,
'File not found message'
;
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$params
= {};
my
$req
= POST(
'action/bogus'
,
@headers
,
Content
=> {
action
=> encode_json(
$params
) } );
my
$res
=
$cb
->(
$req
);
action_response_not_ok(
$res
,
qr{Can't locate Pinto/Action/Bogus.pm}
i );
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
$req
= POST(
'action/nop'
,
Content
=> {
action
=> encode_json({}) } );
my
$res
=
$cb
->(
$req
);
is
$res
->code, 415,
'Unsupported media type status'
;
like
$res
->content,
qr/too old/
;
like
$res
->content,
qr/upgrade pinto/
;
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
@headers
= (
Accept
=>
'application/vnd.pinto.v0+text'
);
my
$req
= POST(
'action/nop'
,
Content
=> {
action
=> encode_json({}) } );
my
$res
=
$cb
->(
$req
);
is
$res
->code, 415,
'Unsupported media type status'
;
like
$res
->content,
qr/too old/
;
like
$res
->content,
qr/upgrade pinto/
;
};
test_psgi
app
=>
$app
,
client
=>
sub
{
my
$cb
=
shift
;
my
@headers
= (
Accept
=>
'application/vnd.pinto.v99+text'
);
my
$req
= POST(
'action/nop'
,
@headers
,
Content
=> {
action
=> encode_json({}) } );
my
$res
=
$cb
->(
$req
);
is
$res
->code, 415,
'Unsupported media type status'
;
like
$res
->content,
qr/too new/
;
like
$res
->content,
qr/upgrade pintod/
;
};
sub
action_response_ok {
my
(
$response
,
$pattern
,
$test_name
) =
@_
;
$test_name
||=
sprintf
'%s %s'
,
$response
->request->method,
$response
->request->uri;
local
$Test::Builder::Level
=
$Test::Builder::Level
+ 3;
my
$type
=
$response
->header(
'Content-Type'
);
is
$type
,
'text/plain'
,
"Content-Type response header from $test_name"
;
my
$status
=
$response
->code;
is
$status
, 200,
"Succesful status code for $test_name"
;
my
$content
=
$response
->content;
like
$content
,
qr{$PINTO_PROTOCOL_STATUS_OK\n$}
,
"Response ends with status-ok for $test_name"
;
like
$content
,
$pattern
,
"Response content matches for $test_name"
if
$pattern
;
}
sub
action_response_not_ok {
my
(
$response
,
$pattern
,
$test_name
) =
@_
;
$test_name
||=
sprintf
'%s %s'
,
$response
->request->method,
$response
->request->uri;
local
$Test::Builder::Level
=
$Test::Builder::Level
+ 3;
my
$type
=
$response
->header(
'Content-Type'
);
is
$type
,
'text/plain'
,
"Content-Type response header from $test_name"
;
my
$status
=
$response
->code;
is
$status
, 200,
"Succesful status code for $test_name"
;
my
$content
=
$response
->content;
unlike
$content
,
qr{$PINTO_PROTOCOL_STATUS_OK\n$}
,
"Response does not end with status-ok for $test_name"
;
like
$content
,
$pattern
,
"Response content matches for $test_name"
if
$pattern
;
}
done_testing;