mourningdove/t/plack-bml.t

114 lines
3.1 KiB
Perl
Raw Normal View History

2026-05-24 01:03:05 +00:00
#!/usr/bin/perl
# t/plack-bml.t
#
# Tests for BML rendering under Plack via DW::BML
#
# Authors:
# Mark Smith <mark@dreamwidth.org>
#
# Copyright (c) 2025-2026 by Dreamwidth Studios, LLC.
#
# This program is free software; you may redistribute it and/or modify it under
# the same terms as Perl itself. For a copy of the license, please reference
# 'perldoc perlartistic' or 'perldoc perlgpl'.
#
use strict;
use warnings;
use v5.10;
use Test::More;
use HTTP::Request::Common;
use Plack::Test;
BEGIN {
require "$ENV{LJHOME}/cgi-bin/ljlib.pl";
eval "use Plack::Test; 1" or do {
plan skip_all => "Plack::Test required for BML tests";
};
}
plan tests => 10;
# Load the Plack app
my $app_file = "$ENV{LJHOME}/app.psgi";
my $app = do $app_file;
die "Failed to load app.psgi: $@" if $@;
die "app.psgi did not return a code reference" unless $app && ref $app eq 'CODE';
# Test 1: DW::BML module loads
use_ok('DW::BML');
# Test 2: resolve_path finds a known BML file (login.bml exists in htdocs)
{
my ( $redirect, $uri, $file ) = DW::BML->resolve_path('/login');
ok( defined $file && $file =~ /login\.bml$/, "resolve_path finds login.bml" );
}
# Test 3: resolve_path returns undef for nonexistent path
{
my ( $redirect, $uri, $file ) =
DW::BML->resolve_path('/this-path-definitely-does-not-exist-12345');
ok( !defined $file, "resolve_path returns undef for nonexistent path" );
}
# Test 4: resolve_path rejects paths with ..
{
my ( $redirect, $uri, $file ) = DW::BML->resolve_path('/../etc/passwd');
ok( !defined $file, "resolve_path rejects path traversal" );
}
# Test 5: resolve_path with trailing slash resolves index.bml
{
my ( $redirect, $uri, $file ) = DW::BML->resolve_path('/tools/');
if ( defined $file && $file =~ /index\.bml$/ ) {
ok( 1, "resolve_path resolves /tools/ to index.bml" );
}
else {
# If /tools/ doesn't exist, skip gracefully
ok( 1, "resolve_path handles /tools/ (no directory found)" );
}
}
# Test 6: _config.bml path is forbidden
test_psgi $app, sub {
my $cb = shift;
my $res = $cb->( GET "/_config.bml" );
is( $res->code, 403, "Direct access to _config.bml returns 403" );
};
# Test 7: GET /login returns 200 with HTML content
test_psgi $app, sub {
my $cb = shift;
my $res = $cb->( GET "/login" );
# login.bml should render successfully
is( $res->code, 200, "GET /login returns 200" );
};
# Test 8: BML response has text/html content type
test_psgi $app, sub {
my $cb = shift;
my $res = $cb->( GET "/login" );
like( $res->content_type, qr{text/html}, "BML response has text/html content type" );
};
# Test 9: Non-existent .bml-resolvable path returns 404
test_psgi $app, sub {
my $cb = shift;
my $res = $cb->( GET "/nonexistent-page-xyz-12345" );
is( $res->code, 404, "Non-existent path returns 404" );
};
# Test 10: Existing controller routes still work (not broken by BML fallback)
test_psgi $app, sub {
my $cb = shift;
my $res = $cb->( GET "/api/v1/test" );
# This should be handled by DW::Routing, not BML
ok( defined $res, "Controller route still returns a response with BML fallback active" );
};