fix: 合并后清理重复测试与修复 CEO/财务兜底脚本注入 bug
- apply-ceo-finance-fallback.js: execute() 原先在传入 mock pool 时仍强制要求 DATABASE_URL 环境变量,导致单测无法注入 mock pool 验证事务逻辑。改为仅在 未传入 pool 时才检查 DATABASE_URL。 - portal.test.js: 删除本次合并前遗留的重复用例(期望旧的 portal.feature_disabled reasonCode),候选分支自带的等价用例更完整 (校验 reasonCode 以及全部零写入断言)。 - todos.test.js: 删除本次合并前遗留的文件,候选分支的 todos.errors.test.js 覆盖等价且更完整。
这个提交包含在:
@@ -164,8 +164,11 @@ function countsEqual(left, right) {
|
||||
.every((field) => Number(left[field]) === Number(right[field]));
|
||||
}
|
||||
|
||||
async function execute(options, pool = new Pool({ connectionString: process.env.DATABASE_URL })) {
|
||||
async function execute(options, pool) {
|
||||
if (!pool) {
|
||||
if (!process.env.DATABASE_URL) throw new Error("missing_database_url");
|
||||
pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
||||
}
|
||||
if (options.apply && process.env[APPLY_ENV_KEY] !== "1") {
|
||||
throw new Error(`apply_requires_${APPLY_ENV_KEY}`);
|
||||
}
|
||||
|
||||
@@ -573,26 +573,4 @@ describe("portal routes", () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
it("returns a precise reasonCode and skips business queries when portal home is disabled", async () => {
|
||||
featureFlagState.portalHome = false;
|
||||
const { app, prisma } = await buildApp({});
|
||||
|
||||
const response = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/portal/home",
|
||||
headers: { authorization: "Bearer test" },
|
||||
});
|
||||
|
||||
expect(response.statusCode).toBe(409);
|
||||
expect(response.json()).toMatchObject({
|
||||
error: {
|
||||
code: "VALID_001",
|
||||
details: { featureFlag: "portal_home_v1_disabled", reason: "env_hard_off", reasonCode: "portal.feature_disabled" },
|
||||
},
|
||||
});
|
||||
expect(prisma.reimbursementForm.count).not.toHaveBeenCalled();
|
||||
expect(prisma.workflowTask.count).not.toHaveBeenCalled();
|
||||
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
const Fastify = require("fastify");
|
||||
const todosRoutes = require("../../../src/routes/todos");
|
||||
const { AppError } = require("../../../src/utils/AppError");
|
||||
|
||||
async function buildApp({ featureEnabled = true } = {}) {
|
||||
const app = Fastify();
|
||||
const prisma = {
|
||||
featureFlag: {
|
||||
findUnique: vi.fn(async () => ({
|
||||
flag_key: "todo_board_v1",
|
||||
override_mode: featureEnabled ? "force_on" : "force_off",
|
||||
rollout_type: "global",
|
||||
department_ids: [],
|
||||
})),
|
||||
},
|
||||
todoItem: {
|
||||
findMany: vi.fn(async () => []),
|
||||
create: vi.fn(),
|
||||
findUnique: vi.fn(),
|
||||
update: vi.fn(),
|
||||
},
|
||||
};
|
||||
app.decorate("prisma", prisma);
|
||||
app.decorate("config", { todoBoardEnabled: true });
|
||||
app.decorate("authenticate", async (request) => {
|
||||
request.employee = { id: "employee-1", department_id: "department-1", permissionCodes: [] };
|
||||
});
|
||||
app.decorate("hasPermission", () => false);
|
||||
app.setErrorHandler((error, request, reply) => {
|
||||
if (error instanceof AppError) {
|
||||
return reply.code(error.statusCode).send({ error: { code: error.code, details: error.details ?? {} } });
|
||||
}
|
||||
return reply.code(500).send({ error: { code: "SYS_001" } });
|
||||
});
|
||||
await app.register(todosRoutes, { prefix: "/api" });
|
||||
return { app, prisma };
|
||||
}
|
||||
|
||||
describe("todos feature gate", () => {
|
||||
it("returns a precise reasonCode and skips todo reads when the board is disabled", async () => {
|
||||
const { app, prisma } = await buildApp({ featureEnabled: false });
|
||||
try {
|
||||
const getResponse = await app.inject({ method: "GET", url: "/api/todos" });
|
||||
expect(getResponse.statusCode).toBe(409);
|
||||
expect(getResponse.json()).toEqual({
|
||||
error: {
|
||||
code: "VALID_001",
|
||||
details: { featureFlag: "todo_board_v1_disabled", reason: "flag_force_off", reasonCode: "todo.feature_disabled" },
|
||||
},
|
||||
});
|
||||
expect(prisma.todoItem.findMany).not.toHaveBeenCalled();
|
||||
|
||||
const postResponse = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/todos",
|
||||
payload: { title: "合成待办" },
|
||||
});
|
||||
expect(postResponse.statusCode).toBe(409);
|
||||
expect(postResponse.json().error.details.reasonCode).toBe("todo.feature_disabled");
|
||||
expect(prisma.todoItem.create).not.toHaveBeenCalled();
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("lists todos normally without leaking a reasonCode when the board is enabled", async () => {
|
||||
const { app, prisma } = await buildApp({ featureEnabled: true });
|
||||
try {
|
||||
const response = await app.inject({ method: "GET", url: "/api/todos" });
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.json().data).toEqual({ items: [] });
|
||||
expect(prisma.todoItem.findMany).toHaveBeenCalledTimes(1);
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
在新工单中引用
屏蔽一个用户