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 )