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 )