Files
ftb-project-management/apps/web/lib/overtime.test.ts
2026-07-02 09:30:50 +08:00

99 lines
2.7 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
filterOvertimeRecordsForViewer,
type OvertimeRecord,
} from './overtime';
import type { Department, Member, RoleItem } from './members';
import type { AuthUser } from './auth-user';
const departments: Department[] = [
{ id: 'dept-tech', name: 'Tech', order: 1, createdAt: '2024-01-01' },
{ id: 'dept-front', name: 'Frontend', parentId: 'dept-tech', order: 1, createdAt: '2024-01-01' },
{ id: 'dept-back', name: 'Backend', parentId: 'dept-tech', order: 2, createdAt: '2024-01-01' },
{ id: 'dept-product', name: 'Product', order: 2, createdAt: '2024-01-01' },
];
const members: Member[] = [
member('m-lead', 'Lead', 'dept-tech', 'role-lead'),
member('m-front', 'Frontend Alice', 'dept-front', 'role-dev'),
member('m-back', 'Backend Bob', 'dept-back', 'role-dev'),
member('m-pm', 'PM Carol', 'dept-product', 'role-pm'),
];
const records: OvertimeRecord[] = [
record('ot-front', 'Frontend Alice'),
record('ot-back', 'Backend Bob'),
record('ot-pm', 'PM Carol'),
];
test('filterOvertimeRecordsForViewer limits non-admin viewers to their department tree', () => {
const visible = filterOvertimeRecordsForViewer(records, {
viewer: toAuthUser(members[0]),
viewerRole: role('role-lead', ['overtime:view']),
members,
departments,
});
assert.deepEqual(visible.map((item) => item.id), ['ot-front', 'ot-back']);
});
test('filterOvertimeRecordsForViewer lets wildcard admin view every department', () => {
const visible = filterOvertimeRecordsForViewer(records, {
viewer: toAuthUser(members[0]),
viewerRole: role('role-admin', ['*']),
members,
departments,
});
assert.deepEqual(visible.map((item) => item.id), ['ot-front', 'ot-back', 'ot-pm']);
});
function member(id: string, name: string, departmentId: string, roleId: string): Member {
return {
id,
name,
username: id.toUpperCase(),
departmentId,
roleId,
phone: '',
email: '',
password: '',
createdAt: '2024-01-01',
};
}
function record(id: string, person: string): OvertimeRecord {
return {
id,
person,
projectId: 'project-1',
startTime: '2026-06-01T19:00',
endTime: '2026-06-01T21:00',
duration: 2,
reasonId: 'reason-1',
createdAt: '2026-06-01',
};
}
function role(id: string, permissions: string[]): RoleItem {
return {
id,
name: id,
createdAt: '2024-01-01',
permissions,
};
}
function toAuthUser(member: Member): AuthUser {
return {
id: member.id,
name: member.name,
username: member.username ?? member.id.toUpperCase(),
roleId: member.roleId,
departmentId: member.departmentId,
email: member.email,
};
}