CGI-Lingua
view release on metacpan or search on metacpan
t/30-basics.t view on Meta::CPAN
my $lingua = CGI::Lingua->new(
supported => ['en'],
cache => $cache,
);
is($lingua->language(), 'English', 'Language resolved via IP country (US)');
};
# Edge case - Loopback IP
subtest 'Localhost IP' => sub {
local %ENV = %{$mock_env};
$ENV{REMOTE_ADDR} = '127.0.0.1';
my $lingua = CGI::Lingua->new(
supported => ['en'],
cache => $cache,
);
ok(!defined $lingua->country(), 'No country for localhost IP');
};
# Time zone detection
subtest 'Time Zone' => sub {
if(-e 't/online.enabled') { # Fix http://www.cpantesters.org/cpan/report/cf983ce4-17db-11f0-894c-9c582d706e6a
local %ENV = %{$mock_env};
my $lingua = CGI::Lingua->new(
supported => ['en'],
cache => $cache,
);
is($lingua->time_zone(), 'America/New_York', 'Time zone from ip-api.com');
}
};
# Unsupported languages
subtest 'Unsupported Language' => sub {
local %ENV = %{$mock_env};
my $lingua = CGI::Lingua->new(
supported => ['fr'],
cache => $cache,
);
is($lingua->language(), 'Unknown', 'No supported languages match request');
like($lingua->requested_language(), qr/English/, 'Shows requested language');
};
subtest 'Locale Detection' => sub {
Test::Mockingbird::mock('Locale::Object::Country', 'name', sub { 'MockCountry' });
Test::Mockingbird::mock('Locale::Object::Country', 'code_alpha2', sub { 'MC' });
# Locale from Locale::Object::Country
subtest 'From User-Agent' => sub {
local %ENV = (
%{$mock_env},
HTTP_USER_AGENT => 'Mozilla/5.0 (X11; Linux x86_64; rv:91.0) en-US'
);
my $lingua = CGI::Lingua->new(supported => ['en']);
my $locale = $lingua->locale();
isa_ok($locale, 'Locale::Object::Country', 'Locale object');
is($locale->code_alpha2(), 'MC', 'Correct country from Locale::Object::Country');
};
# Invalid country code
subtest 'Invalid Code' => sub {
local %ENV = %{$mock_env};
$ENV{GEOIP_COUNTRY_CODE} = 'XX';
# Mock _code2country to return our mock country object
Test::Mockingbird::mock('CGI::Lingua', '_code2country', sub {
my ($self, $code) = @_;
return bless { code => lc $code }, 'Locale::Object::Country';
});
my $lingua = CGI::Lingua->new(supported => ['en']);
Test::Mockingbird::mock('CGI::Lingua', '_code2country', sub { undef });
ok(!defined $lingua->locale(), 'Undefined for invalid country code');
};
{ local $SIG{__WARN__} = sub {}; Test::Mockingbird::restore_all() }
};
subtest 'IPv6 Handling' => sub {
my $ipv6_public = '2001:db8::1'; # Test documentation IP
my $ipv6_private = 'fd00::1'; # ULA private IP
my $ipv6_loopback = '::1';
my $ipv6_v4mapped = '::ffff:8.8.8.8'; # Google DNS â public, not TEST-NET-1
# Mock IP::Country for IPv6
Test::Mockingbird::mock('IP::Country::Fast', 'inet_atocc', sub {
my ($self, $ip) = @_;
return $ip eq $ipv6_public ? 'DE' : undef;
});
subtest 'Public IPv6' => sub {
local %ENV = (%{$mock_env}, REMOTE_ADDR => $ipv6_public);
my $lingua = CGI::Lingua->new(
supported => ['en'],
cache => $cache,
);
is($lingua->country, 'de', 'Country from IPv6 via IP::Country mock');
ok($cache->get("CGI::Lingua:country:$ipv6_public"), 'IPv6 result cached');
};
subtest 'Private IPv6' => sub {
local %ENV = (%{$mock_env}, REMOTE_ADDR => $ipv6_private);
my $lingua = CGI::Lingua->new(supported => ['en']);
ok(!defined $lingua->country, 'Undefined for private IPv6');
};
subtest 'Loopback IPv6' => sub {
local %ENV = (%{$mock_env}, REMOTE_ADDR => $ipv6_loopback);
my $lingua = CGI::Lingua->new(supported => ['en']);
ok(!defined $lingua->country, 'Undefined for IPv6 loopback');
};
subtest 'v4-Mapped IPv6' => sub {
local %ENV = (%{$mock_env}, REMOTE_ADDR => $ipv6_v4mapped);
my $lingua = CGI::Lingua->new(
supported => ['en'],
cache => $cache,
);
# Should treat as IPv4 192.0.2.1
Test::Mockingbird::mock('IP::Country::Fast', 'inet_atocc', sub { 'US' });
is($lingua->country, 'us', 'Handle v4-mapped IPv6 as IPv4');
};
subtest 'Fallback to External API' => sub {
local %ENV = (%{$mock_env}, REMOTE_ADDR => $ipv6_public);
# Disable IP::Country mock
( run in 1.970 second using v1.01-cache-2.11-cpan-302cb4679cc )