- 后端:Bun + Hono + Drizzle ORM + SQLite - 前端:Vue 3 + Naive UI + ECharts - 项目管理:创建项目 + 绑定 Git 仓库 - OKR 系统:目标/关键结果 CRUD + 进度追踪 - Git 同步:Gitea API 自动同步 commit/PR + 作者关联 - 数据看板:项目 OKR 进度 + KR 状态分布 + 代码活动 - 权限体系:admin/manager/developer/viewer 四级 - Docker 部署:docker-compose + nginx Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
86 lines
2.1 KiB
TypeScript
86 lines
2.1 KiB
TypeScript
/**
|
|
* Test setup for DevPerf Dashboard Backend
|
|
*
|
|
* This file provides common test utilities and mock helpers for the
|
|
* Hono-based API test suite. Since the real DB requires SQLite and
|
|
* Drizzle migrations, unit tests operate on the Hono app directly
|
|
* using Hono's built-in test client (app.request).
|
|
*/
|
|
|
|
import { SignJWT } from 'jose';
|
|
|
|
// Shared test JWT secret (matches .env.example)
|
|
export const TEST_JWT_SECRET = 'test-secret-for-unit-tests-at-least-16-chars';
|
|
const secret = new TextEncoder().encode(TEST_JWT_SECRET);
|
|
|
|
/**
|
|
* Generate a valid JWT token for test requests.
|
|
*/
|
|
export async function createTestToken(payload: {
|
|
sub: string;
|
|
email: string;
|
|
role: string;
|
|
displayName: string;
|
|
}): Promise<string> {
|
|
return new SignJWT(payload)
|
|
.setProtectedHeader({ alg: 'HS256' })
|
|
.setIssuedAt()
|
|
.setExpirationTime('1h')
|
|
.sign(secret);
|
|
}
|
|
|
|
/**
|
|
* Standard test user fixtures.
|
|
*/
|
|
export const TEST_USERS = {
|
|
admin: {
|
|
sub: 'user-admin-001',
|
|
email: 'admin@test.com',
|
|
role: 'admin',
|
|
displayName: 'Test Admin',
|
|
},
|
|
manager: {
|
|
sub: 'user-mgr-001',
|
|
email: 'manager@test.com',
|
|
role: 'manager',
|
|
displayName: 'Test Manager',
|
|
},
|
|
developer: {
|
|
sub: 'user-dev-001',
|
|
email: 'dev@test.com',
|
|
role: 'developer',
|
|
displayName: 'Test Developer',
|
|
},
|
|
viewer: {
|
|
sub: 'user-viewer-001',
|
|
email: 'viewer@test.com',
|
|
role: 'viewer',
|
|
displayName: 'Test Viewer',
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Helper to build request with auth header.
|
|
*/
|
|
export function authHeaders(token: string): Record<string, string> {
|
|
return {
|
|
Authorization: `Bearer ${token}`,
|
|
'Content-Type': 'application/json',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Assert a JSON response matches the standard ApiResponse shape.
|
|
*/
|
|
export function assertApiResponse(body: any) {
|
|
if (typeof body.code !== 'number') {
|
|
throw new Error(`Expected body.code to be a number, got ${typeof body.code}`);
|
|
}
|
|
if (typeof body.message !== 'string') {
|
|
throw new Error(`Expected body.message to be a string, got ${typeof body.message}`);
|
|
}
|
|
if (!('data' in body)) {
|
|
throw new Error('Expected body to have a "data" property');
|
|
}
|
|
}
|