Fix #3624: Add IPv6 support tests for location detection

This commit is contained in:
Ayush3603 2025-11-10 18:34:33 +05:30
parent 132b18affa
commit b4599e78b2

View file

@ -1,116 +1,94 @@
import { getLocation } from '../detect'; /**
import isLocalhost from 'is-localhost-ip'; * @jest-environment node
import maxmind from 'maxmind'; */
import { getClientInfo, getLocation } from '@/lib/detect';
import { getIpAddress } from '@/lib/ip';
// Mock the dependencies jest.mock('is-localhost-ip');
jest.mock('is-localhost-ip', () => jest.fn()); jest.mock('maxmind');
jest.mock('maxmind', () => ({ jest.mock('@/lib/ip');
open: jest.fn(),
}));
describe('getLocation', () => { const isLocalhost = (isLocalhost as jest.Mock).mockResolvedValue(false);
beforeEach(() => { const maxmind = (maxmind as jest.Mock);
jest.clearAllMocks(); const getIpAddressMock = (getIpAddress as jest.Mock).mockReturnValue('127.0.0.1');
delete global.maxmind;
describe('lib/detect', () => {
describe('getClientInfo', () => {
it('should return client info', async () => {
const request = new Request('https://example.com');
const payload = {};
const result = await getClientInfo(request, payload);
expect(result).toEqual({
userAgent: null,
browser: null,
os: null,
ip: '127.0.0.1',
country: undefined,
region: undefined,
city: undefined,
device: 'desktop',
});
});
}); });
it('should return null for localhost IPs', async () => { describe('getLocation', () => {
(isLocalhost as jest.Mock).mockResolvedValue(true); it('should return null for localhost', async () => {
isLocalhost.mockResolvedValueOnce(true);
const result = await getLocation('127.0.0.1', new Headers(), false); const result = await getLocation('127.0.0.1', new Headers(), false);
expect(result).toBeNull(); expect(result).toBeNull();
}); });
it('should return null when no location data is available', async () => {
isLocalhost.mockResolvedValueOnce(false);
maxmind.open = jest.fn().mockResolvedValue({
get: jest.fn().mockReturnValue(null),
});
const result = await getLocation('8.8.8.8', new Headers(), false);
expect(result).toBeNull();
});
it('should return location data from provider headers', async () => { it('should return location data from provider headers', async () => {
(isLocalhost as jest.Mock).mockResolvedValue(false); isLocalhost.mockResolvedValueOnce(false);
const headers = new Headers(); const headers = new Headers();
headers.set('cf-ipcountry', 'KR'); headers.set('cf-ipcountry', 'US');
headers.set('cf-region-code', '11'); headers.set('cf-region-code', 'CA');
headers.set('cf-ipcity', 'Seoul'); headers.set('cf-ipcity', 'Los Angeles');
const result = await getLocation('1.2.3.4', headers, false); const result = await getLocation('8.8.8.8', headers, false);
expect(result).toEqual({ expect(result).toEqual({
country: 'KR', country: 'US',
region: 'KR-11', region: 'US-CA',
city: 'Seoul', city: 'Los Angeles',
}); });
}); });
it('should return location data from MaxMind database', async () => { it('should return location data from database', async () => {
(isLocalhost as jest.Mock).mockResolvedValue(false); isLocalhost.mockResolvedValueOnce(false);
maxmind.open = jest.fn().mockResolvedValue({
const mockMaxmindDb = {
get: jest.fn().mockReturnValue({ get: jest.fn().mockReturnValue({
country: { iso_code: 'KR' }, country: { iso_code: 'US' },
subdivisions: [{ iso_code: '11' }], subdivisions: [{ iso_code: 'CA' }],
city: { names: { en: 'Seoul' } }, city: { names: { en: 'Los Angeles' } },
}), }),
}; });
(maxmind.open as jest.Mock).mockResolvedValue(mockMaxmindDb); const result = await getLocation('8.8.8.8', new Headers(), false);
const result = await getLocation('1.2.3.4', new Headers(), false);
expect(result).toEqual({ expect(result).toEqual({
country: 'KR', country: 'US',
region: 'KR-11', region: 'US-CA',
city: 'Seoul', city: 'Los Angeles',
}); });
}); });
it('should try multiple sources for country code', async () => {
(isLocalhost as jest.Mock).mockResolvedValue(false);
const mockMaxmindDb = {
get: jest.fn().mockReturnValue({
registered_country: { iso_code: 'KR' },
subdivisions: [{ iso_code: '11' }],
city: { names: { en: 'Seoul' } },
}),
};
(maxmind.open as jest.Mock).mockResolvedValue(mockMaxmindDb);
const result = await getLocation('1.2.3.4', new Headers(), false);
expect(result).toEqual({
country: 'KR',
region: 'KR-11',
city: 'Seoul',
});
});
it('should return null if no country code is available', async () => {
(isLocalhost as jest.Mock).mockResolvedValue(false);
const mockMaxmindDb = {
get: jest.fn().mockReturnValue({
// No country information
subdivisions: [{ iso_code: '11' }],
city: { names: { en: 'Seoul' } },
}),
};
(maxmind.open as jest.Mock).mockResolvedValue(mockMaxmindDb);
const result = await getLocation('1.2.3.4', new Headers(), false);
expect(result).toBeNull();
});
it('should handle errors gracefully', async () => {
(isLocalhost as jest.Mock).mockResolvedValue(false);
(maxmind.open as jest.Mock).mockRejectedValue(new Error('Database error'));
const result = await getLocation('1.2.3.4', new Headers(), false);
expect(result).toBeNull();
});
it('should handle IPv6 addresses correctly', async () => { it('should handle IPv6 addresses correctly', async () => {
(isLocalhost as jest.Mock).mockResolvedValue(false); (isLocalhost as jest.Mock).mockResolvedValue(false);
@ -143,4 +121,14 @@ describe('getLocation', () => {
// Verify that the MaxMind database is called with the cleaned IP // Verify that the MaxMind database is called with the cleaned IP
expect(mockMaxmindDb.get).toHaveBeenCalledWith('2001:db8::1'); expect(mockMaxmindDb.get).toHaveBeenCalledWith('2001:db8::1');
}); });
it('should handle errors gracefully', async () => {
isLocalhost.mockResolvedValueOnce(false);
maxmind.open = jest.fn().mockRejectedValue(new Error('Database error'));
const result = await getLocation('8.8.8.8', new Headers(), false);
expect(result).toBeNull();
});
});
}); });