CGI-Lingua
view release on metacpan or search on metacpan
t/edge_cases.t view on Meta::CPAN
#!/usr/bin/env perl
# t/edge_cases.t -- Hostile, pathological, boundary-condition, and security
# tests for CGI::Lingua.
#
# Strategy: every subtest actively tries to break, inject, overflow, or
# subvert the module. Inputs are chosen specifically to probe the validation
# and sanitisation layer rather than the happy path.
use strict;
use warnings;
use CHI;
use Readonly;
use Scalar::Util qw(blessed weaken);
use Test::Most;
use Test::Mockingbird;
use Test::Returns qw(returns_ok);
use lib 't/lib';
BEGIN { use_ok('CGI::Lingua') }
# Pre-require lazily-loaded modules before installing mocks
my $HAS_LWP = eval { require LWP::Simple::WithCache; 1 } ? 1 : 0;
my $HAS_JSON = eval { require JSON::Parse; 1 } ? 1 : 0;
# ââ Constants âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Readonly my %LANG => (EN => 'en', FR => 'fr', EN_GB => 'en-gb');
Readonly my %IP => (
PUBLIC => '8.8.8.8',
LOOPBACK => '127.0.0.1',
PRIVATE => '192.168.1.1',
);
# Accept-Language header string of exactly ACCEPT_LANG_MAX (256) chars.
Readonly my $ACCEPT_LANG_AT_MAX => 'a' x 256;
# One byte over the documented 256-byte cap.
Readonly my $ACCEPT_LANG_OVER => 'a' x 257;
# String of 'a' chars long enough to stress the limit.
Readonly my $ACCEPT_LANG_HUGE => 'a' x 10_000;
# Cache namespace as defined in the module constant CACHE_NS.
Readonly my $CACHE_NS => 'CGI::Lingua:';
# ââ Global network block ââââââââââââââââââââââââââââââââââââââââââââââââââââââ
_block_network();
# ââ Helpers âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
sub _block_network {
Test::Mockingbird::mock('CGI::Lingua', '_resolve_country_via_whois', sub { });
Test::Mockingbird::mock('LWP::Simple::WithCache', 'get', sub { undef })
if $HAS_LWP;
}
sub _obj {
my ($supported, %extra) = @_;
CGI::Lingua->new(supported => $supported, %extra);
}
# Inject "IP::Country present but returns the given code" for a fresh object.
sub _inject_ipcountry {
my ($l, $cc) = @_;
Test::Mockingbird::mock('IP::Country::Fast', 'inet_atocc', sub { $cc });
$l->{_have_ipcountry} = 1;
$l->{_ipcountry} = bless {}, 'IP::Country::Fast';
$l->{_have_geoip} = 0;
$l->{_have_geoipfree} = 0;
}
# âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
# SECTION 1: Constructor hostile inputs
( run in 1.211 second using v1.01-cache-2.11-cpan-364913b4093 )