Chandra
view release on metacpan or search on metacpan
t/46_assets_edge.t view on Meta::CPAN
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
BEGIN {
eval { require File::Raw };
plan skip_all => 'File::Raw required for Chandra::Assets tests' if $@;
}
use File::Temp qw(tempdir);
use File::Path qw(mkpath);
use_ok('Chandra::Assets');
my $dir = tempdir(CLEANUP => 1);
mkpath("$dir/sub/deep");
sub _write {
my ($path, $content) = @_;
open my $fh, '>', $path or die "Cannot write $path: $!";
print $fh $content;
close $fh;
}
_write("$dir/file.txt", "hello");
_write("$dir/empty.css", "");
_write("$dir/sub/nested.js", "var x = 1;");
_write("$dir/sub/deep/a.css", "a {}");
_write("$dir/binary.bin", "\x00\x01\x02\x03");
_write("$dir/has spaces.txt", "spaced");
_write("$dir/UPPER.CSS", "upper");
# ---- Path traversal attempts ----
{
my $a = Chandra::Assets->new(root => $dir);
my @bad_paths = (
'../etc/passwd',
'../../root/.ssh/id_rsa',
'sub/../../etc/shadow',
'sub/../../../outside',
);
for my $bad (@bad_paths) {
eval { $a->read($bad) };
like($@, qr/traversal/i, "blocked: $bad");
}
}
# ---- Backslash rejection ----
{
my $a = Chandra::Assets->new(root => $dir);
eval { $a->read('sub\\nested.js') };
like($@, qr/traversal/i, 'backslash path rejected');
}
# ---- Empty file ----
{
my $a = Chandra::Assets->new(root => $dir);
my $content = $a->read('empty.css');
is($content, '', 'read empty file returns empty string');
my $tag = $a->inline_css('empty.css');
is($tag, '<style></style>', 'inline_css on empty file');
}
# ---- Binary file read ----
{
my $a = Chandra::Assets->new(root => $dir);
my $content = $a->read('binary.bin');
ok(defined $content, 'read binary file');
is(length($content), 4, 'binary content correct length');
}
# ---- Missing file ----
{
my $a = Chandra::Assets->new(root => $dir);
ok(!$a->exists('nonexistent.xyz'), 'missing file not found');
eval { $a->inline_css('nonexistent.css') };
like($@, qr/Cannot read/, 'inline_css on missing file croaks');
eval { $a->inline_js('nonexistent.js') };
like($@, qr/Cannot read/, 'inline_js on missing file croaks');
eval { $a->inline_image('nonexistent.png') };
like($@, qr/Cannot read/, 'inline_image on missing file croaks');
}
# ---- Unicode filename ----
{
my $a = Chandra::Assets->new(root => $dir);
my $uname = "caf\xc3\xa9.txt"; # UTF-8 bytes for café
eval { _write("$dir/$uname", "unicode content") };
SKIP: {
skip "filesystem doesn't support unicode", 2 if $@ || !-f "$dir/$uname";
ok($a->exists($uname), 'unicode filename exists');
( run in 0.688 second using v1.01-cache-2.11-cpan-5b529ec07f3 )