Merge branch 'whats-left'

This commit is contained in:
RevIQ
2026-01-10 18:10:40 +08:00
2 changed files with 118 additions and 1 deletions

View File

@@ -1,10 +1,18 @@
import { beforeEach, describe, expect, test } from "bun:test"; import {
afterAll,
beforeAll,
beforeEach,
describe,
expect,
test,
} from "bun:test";
import { import {
_resetForTesting, _resetForTesting,
_setReaderForTesting, _setReaderForTesting,
extractClientIP, extractClientIP,
getGeoInfo, getGeoInfo,
getUserAgent, getUserAgent,
initGeoReader,
lookupGeoFromIP, lookupGeoFromIP,
} from "./geo.js"; } from "./geo.js";
@@ -220,3 +228,110 @@ describe("getUserAgent", () => {
expect(getUserAgent(createHeaders({}))).toBe("Unknown"); expect(getUserAgent(createHeaders({}))).toBe("Unknown");
}); });
}); });
describe("initGeoReader", () => {
beforeEach(() => {
_resetForTesting();
});
test("calling initGeoReader twice does not reinitialize", async () => {
// First call initializes
await initGeoReader();
// Second call should return early (covers the early return branch)
await initGeoReader();
// If we get here without error, the early return worked
expect(true).toBe(true);
});
test("handles missing database file gracefully", async () => {
// Save original env
const originalPath = Bun.env.GEOIP_DATABASE_PATH;
// Point to non-existent file
Bun.env.GEOIP_DATABASE_PATH = "/nonexistent/path/to/db.mmdb";
// Should not throw, just log a warning
await initGeoReader();
// Lookups should return nulls since reader failed to initialize
expect(lookupGeoFromIP("8.8.8.8")).toEqual({
city: null,
region: null,
country: null,
});
// Restore original env
if (originalPath) {
Bun.env.GEOIP_DATABASE_PATH = originalPath;
} else {
delete Bun.env.GEOIP_DATABASE_PATH;
}
});
});
// Only run real database tests if GEOIP_DATABASE_PATH is set
const hasGeoDatabase = !!Bun.env.GEOIP_DATABASE_PATH;
describe.skipIf(!hasGeoDatabase)("real GeoIP database", () => {
beforeAll(async () => {
_resetForTesting();
await initGeoReader();
});
afterAll(() => {
_resetForTesting();
});
test("looks up Google DNS (8.8.8.8) - US", () => {
const result = lookupGeoFromIP("8.8.8.8");
expect(result.country).toBe("US");
});
test("looks up Cloudflare DNS (1.1.1.1) - AU", () => {
const result = lookupGeoFromIP("1.1.1.1");
// Cloudflare's 1.1.1.1 is geolocated to Sydney, Australia
expect(result.country).toBe("AU");
});
test("looks up known German IP", () => {
// Deutsche Telekom IP range
const result = lookupGeoFromIP("80.150.6.143");
expect(result.country).toBe("DE");
});
test("looks up known UK IP", () => {
// BBC IP range
const result = lookupGeoFromIP("212.58.244.71");
expect(result.country).toBe("GB");
});
test("returns city data for major IPs", () => {
const result = lookupGeoFromIP("8.8.8.8");
// DBIP returns "Mountain View" for Google DNS
expect(result.city).toBe("Mountain View");
expect(result.region).toBe("California");
});
test("getGeoInfo uses real database when no CF headers", () => {
const headers = createHeaders({ "X-Real-IP": "8.8.8.8" });
const result = getGeoInfo(headers);
expect(result.ip).toBe("8.8.8.8");
expect(result.country).toBe("US");
expect(result.city).toBe("Mountain View");
});
test("returns nulls for private/reserved IPs", () => {
const result = lookupGeoFromIP("192.168.1.1");
expect(result.city).toBeNull();
expect(result.country).toBeNull();
});
test("returns nulls for localhost", () => {
const result = lookupGeoFromIP("127.0.0.1");
expect(result.city).toBeNull();
expect(result.country).toBeNull();
});
});

View File

@@ -7,6 +7,7 @@
git git
dbmate dbmate
ast-grep ast-grep
dbip-city-lite
]; ];
dotenv.enable = true; dotenv.enable = true;
@@ -39,6 +40,7 @@
env = { env = {
DATABASE_URL = "postgres://reviq:reviq@localhost/reviq-dashboard?sslmode=disable"; DATABASE_URL = "postgres://reviq:reviq@localhost/reviq-dashboard?sslmode=disable";
TEST_DATABASE_URL = "postgres://reviq:reviq@localhost/reviq-dashboard_test?sslmode=disable"; TEST_DATABASE_URL = "postgres://reviq:reviq@localhost/reviq-dashboard_test?sslmode=disable";
GEOIP_DATABASE_PATH = "${pkgs.dbip-city-lite}/share/dbip/dbip-city-lite.mmdb";
}; };
scripts = { scripts = {