Swadhin Biswas Feature/ai code reviewer (#73) · 8/2/2026
105a287
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/**
* Integration tests for GET /api/admin/stats
*/
import { beforeEach, describe, expect, it, vi } from "vitest";
/* ─── hoisted mocks ─── */
const mocks = vi.hoisted(() => ({
selectMock: vi.fn(),
fakeSchema: {
repositories: { languages: "languages" },
users: {},
pullRequests: { state: "state" },
commits: { stats: "stats", authorDate: "authorDate" },
issues: { state: "state" },
activities: { userId: "userId", createdAt: "createdAt" },
releases: {},
pipelineRunners: { status: "status" },
},
}));
vi.mock("@/db", () => ({
getDatabase: () => mockDb,
schema: mocks.fakeSchema,
}));
vi.mock("@/lib/errors", () => ({
withErrorHandler: (fn: any) => fn,
}));
vi.mock("drizzle-orm", () => ({
count: vi.fn(() => "count_expr"),
desc: vi.fn(),
eq: vi.fn(),
gte: vi.fn(),
}));
/* ─── helpers ─── */
function makeDb() {
const chainable = {
from: vi.fn().mockReturnThis(),
where: vi.fn().mockReturnThis(),
limit: vi.fn().mockResolvedValue([{ count: 5 }]),
then: vi.fn().mockImplementation((resolve: any) => resolve([])),
};
return {
select: vi.fn().mockReturnValue(chainable),
selectDistinct: vi.fn().mockReturnValue({
from: vi.fn().mockReturnValue({
where: vi.fn().mockResolvedValue([{ userId: "usr_1" }]),
}),
}),
query: {
users: {
findMany: vi
.fn()
.mockResolvedValue([
{ username: "alice", createdAt: new Date(), avatarUrl: null },
]),
},
activities: {
findMany: vi.fn().mockResolvedValue([
{
id: "act_1",
type: "PUSH",
action: "pushed",
targetType: "branch",
createdAt: new Date(),
user: { username: "alice" },
repository: { name: "my-repo" },
},
]),
},
},
};
}
let mockDb: ReturnType<typeof makeDb>;
const readJson = (r: Response) => r.json();
function ctx(isAdmin: boolean) {
return {
locals: {
user: isAdmin
? { id: "usr_1", username: "admin", isAdmin: true }
: { id: "usr_2", username: "user", isAdmin: false },
},
} as any;
}
/* ─── import route ─── */
import { GET } from "@/pages/api/admin/stats";
/* ─── tests ─── */
describe("GET /api/admin/stats", () => {
beforeEach(() => {
vi.clearAllMocks();
mockDb = makeDb();
});
it("returns 200 with stats for admin user", async () => {
const res = await GET(ctx(true));
expect(res.status).toBe(200);
const json = await readJson(res);
expect(json.data.totalRepos).toBeDefined();
expect(json.data.totalUsers).toBeDefined();
expect(json.data.systemStatus).toBeDefined();
expect(json.data.systemStatus.cpuLoad).toBeGreaterThanOrEqual(0);
expect(json.data.systemStatus.memoryUsage).toBeGreaterThanOrEqual(0);
});
it("returns 403 for non-admin user", async () => {
const res = await GET(ctx(false));
expect(res.status).toBe(403);
});
it("returns 403 when no user", async () => {
const res = await GET({ locals: {} } as any);
expect(res.status).toBe(403);
});
it("returns quickStats", async () => {
const res = await GET(ctx(true));
const json = await readJson(res);
expect(json.data.quickStats).toBeDefined();
expect(typeof json.data.quickStats.commitsToday).toBe("number");
expect(typeof json.data.quickStats.activeUsers).toBe("number");
});
it("returns languages stats", async () => {
const res = await GET(ctx(true));
const json = await readJson(res);
expect(json.data.languages).toBeDefined();
expect(Array.isArray(json.data.languages)).toBe(true);
});
it("returns recentActivity", async () => {
const res = await GET(ctx(true));
const json = await readJson(res);
expect(json.data.recentActivity).toBeDefined();
expect(Array.isArray(json.data.recentActivity)).toBe(true);
});
});