Chandra
view release on metacpan or search on metacpan
t/45_assets.t view on Meta::CPAN
# ---- MIME type detection ----
{
my $a = Chandra::Assets->new(root => $dir);
my @cases = (
['style.css', 'text/css'],
['main.js', 'application/javascript'],
['page.html', 'text/html'],
['data.json', 'application/json'],
['logo.png', 'image/png'],
['photo.jpg', 'image/jpeg'],
['photo.jpeg', 'image/jpeg'],
['icon.gif', 'image/gif'],
['icon.svg', 'image/svg+xml'],
['icon.ico', 'image/x-icon'],
['icon.webp', 'image/webp'],
['font.woff', 'font/woff'],
['font.woff2', 'font/woff2'],
['font.ttf', 'font/ttf'],
['font.eot', 'application/vnd.ms-fontobject'],
['audio.mp3', 'audio/mpeg'],
['video.mp4', 'video/mp4'],
['video.webm', 'video/webm'],
['STYLE.CSS', 'text/css'], # case insensitive
['noext', 'application/octet-stream'],
);
for my $case (@cases) {
is($a->mime_type($case->[0]), $case->[1], "mime_type($case->[0])");
}
}
# ---- read ----
{
my $a = Chandra::Assets->new(root => $dir);
is($a->read('css/style.css'), "body { color: red; }", 'read css file');
is($a->read('js/main.js'), "console.log('hello');", 'read js file');
is($a->read('index.html'), "<html><body>hi</body></html>", 'read html');
is($a->read('data.json'), '{"key":"value"}', 'read json');
}
# ---- exists ----
{
my $a = Chandra::Assets->new(root => $dir);
ok($a->exists('css/style.css'), 'exists: css file');
ok($a->exists('index.html'), 'exists: html file');
ok(!$a->exists('nonexistent.txt'), 'exists: missing file');
}
# ---- path traversal protection ----
{
my $a = Chandra::Assets->new(root => $dir);
eval { $a->read('../etc/passwd') };
like($@, qr/traversal/, 'path traversal with .. blocked');
eval { $a->read('css/../../etc/passwd') };
like($@, qr/traversal/, 'path traversal mid-path blocked');
ok(!$a->exists('../etc/passwd'), 'exists returns false for traversal');
}
# ---- list ----
{
my $a = Chandra::Assets->new(root => $dir);
my @all = $a->list;
ok(scalar @all > 0, 'list returns entries');
# Check that subdirs appear
my %seen = map { $_ => 1 } @all;
ok($seen{'css'} || $seen{'index.html'}, 'list includes known entries');
}
{
my $a = Chandra::Assets->new(root => "$dir/css");
my @css = $a->list('*.css');
ok(scalar @css >= 2, 'list with *.css filter');
for my $f (@css) {
like($f, qr/\.css$/, "filtered entry ends with .css: $f");
}
}
# ---- inline_css ----
{
my $a = Chandra::Assets->new(root => $dir);
my $tag = $a->inline_css('css/style.css');
is($tag, '<style>body { color: red; }</style>', 'inline_css wraps in style tags');
}
# ---- inline_js ----
{
my $a = Chandra::Assets->new(root => $dir);
my $tag = $a->inline_js('js/main.js');
is($tag, "<script>console.log('hello');</script>", 'inline_js wraps in script tags');
}
# ---- inline_image ----
{
my $a = Chandra::Assets->new(root => $dir);
# Use a known small binary content
my $img_path = "$dir/images/test.png";
_write($img_path, "\x89PNG\r\n");
my $tag = $a->inline_image('images/test.png');
like($tag, qr/^<img src="data:image\/png;base64,/, 'inline_image starts correctly');
like($tag, qr/">$/, 'inline_image ends correctly');
}
# ---- bundle ----
{
my $a = Chandra::Assets->new(root => $dir);
my $result = $a->bundle(
css => ['css/reset.css', 'css/style.css'],
( run in 0.590 second using v1.01-cache-2.11-cpan-ceb78f64989 )