fix: support fuzzy logs user search
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
||||
|
||||
const queryMock = mock(async () => [
|
||||
type QueryRow = Record<string, unknown>;
|
||||
type QueryParams = Array<string | number | boolean | null>;
|
||||
|
||||
const queryMock = mock(async (): Promise<QueryRow[]> => [
|
||||
{
|
||||
date: "2026-04-01 13:00:00",
|
||||
calls: 1,
|
||||
@@ -16,12 +19,12 @@ mock.module("./db", () => ({
|
||||
query: queryMock,
|
||||
}));
|
||||
|
||||
const { getTrends, getUserDetail } = await import("./queries");
|
||||
const { getLogs, getTrends, getUserDetail } = await import("./queries");
|
||||
|
||||
describe("getTrends", () => {
|
||||
beforeEach(() => {
|
||||
queryMock.mockClear();
|
||||
queryMock.mockImplementation(async () => [
|
||||
queryMock.mockImplementation(async (): Promise<QueryRow[]> => [
|
||||
{
|
||||
date: "2026-04-01 13:00:00",
|
||||
calls: 1,
|
||||
@@ -62,7 +65,7 @@ describe("getUserDetail", () => {
|
||||
});
|
||||
|
||||
test("returns token breakdown with nested model rows for user details", async () => {
|
||||
queryMock.mockImplementation(async (sql: string) => {
|
||||
queryMock.mockImplementation(async (sql: string): Promise<QueryRow[]> => {
|
||||
if (sql.includes("token_models AS")) {
|
||||
return [
|
||||
{ token_name: "prod-key", model: "claude-sonnet-4", calls: 3, tokens: 100, cache_creation: 5, cache_read: 7, quota: 50 },
|
||||
@@ -123,3 +126,51 @@ describe("getUserDetail", () => {
|
||||
expect(queryMock.mock.calls.some(([sql]) => String(sql).includes("token_name"))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getLogs", () => {
|
||||
beforeEach(() => {
|
||||
queryMock.mockClear();
|
||||
queryMock.mockImplementation(async (sql: string): Promise<QueryRow[]> => {
|
||||
if (sql.includes("SELECT COUNT(*)::int as total")) {
|
||||
return [{ total: 0 }];
|
||||
}
|
||||
|
||||
if (sql.includes("SELECT id, display_name FROM users")) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (sql.includes("SELECT id, name FROM channels")) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
});
|
||||
});
|
||||
|
||||
test("filters logs by fuzzy display name through the users table", async () => {
|
||||
await getLogs({ startTs: 501, endTs: 601, username: "张三" });
|
||||
|
||||
const countCall = queryMock.mock.calls[0];
|
||||
const countSql = String(countCall[0]);
|
||||
const countParams = countCall[1] as QueryParams;
|
||||
|
||||
expect(countSql).toContain("username ILIKE $3");
|
||||
expect(countSql).toContain("SELECT id FROM users");
|
||||
expect(countSql).toContain("display_name ILIKE $3");
|
||||
expect(countSql).toContain("users.username ILIKE $3");
|
||||
expect(countParams).toEqual([501, 601, "%张三%"]);
|
||||
});
|
||||
|
||||
test("uses the same fuzzy user filter for paginated log rows", async () => {
|
||||
await getLogs({ page: 2, pageSize: 25, username: "adm" });
|
||||
|
||||
const dataCall = queryMock.mock.calls[3];
|
||||
const dataSql = String(dataCall[0]);
|
||||
const dataParams = dataCall[1] as QueryParams;
|
||||
|
||||
expect(dataSql).toContain("username ILIKE $1");
|
||||
expect(dataSql).toContain("display_name ILIKE $1");
|
||||
expect(dataSql).toContain("users.username ILIKE $1");
|
||||
expect(dataParams).toEqual(["%adm%", 25, 25]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user