203 lines
6.5 KiB
TypeScript
203 lines
6.5 KiB
TypeScript
/**
|
|
* 测试成员 API 的历史记录集成
|
|
*
|
|
* 通过直接调用数据库来模拟 API 调用,验证历史记录功能
|
|
*/
|
|
|
|
import { prisma } from '../lib/prisma'
|
|
import { getMemberHistory, recordMemberHistory } from '../lib/member-history'
|
|
|
|
async function testMemberAPIHistory() {
|
|
console.log('🧪 测试成员 API 历史记录集成...\n')
|
|
|
|
try {
|
|
// 1. 查找测试用的家族树和用户
|
|
const tree = await prisma.familyTree.findFirst()
|
|
if (!tree) {
|
|
console.error('❌ 未找到测试用的家族树')
|
|
return
|
|
}
|
|
|
|
const userId = tree.ownerId
|
|
console.log('✅ 测试家族树:', tree.name)
|
|
console.log('✅ 测试用户ID:', userId)
|
|
console.log()
|
|
|
|
// 2. 模拟 POST /api/trees/[treeId]/members - 创建成员
|
|
console.log('📝 测试 API: POST /api/trees/[treeId]/members')
|
|
console.log(' 模拟创建成员...')
|
|
|
|
const newMember = await prisma.familyMember.create({
|
|
data: {
|
|
treeId: tree.id,
|
|
surname: 'API',
|
|
givenName: '测试',
|
|
fullName: 'API测试',
|
|
gender: 'MALE',
|
|
generation: 1,
|
|
birthDate: '1995-06-15',
|
|
}
|
|
})
|
|
console.log(' ✅ 成员已创建:', newMember.fullName)
|
|
|
|
// API 应该调用 recordMemberHistory
|
|
await recordMemberHistory({
|
|
memberId: newMember.id,
|
|
treeId: tree.id,
|
|
changedBy: userId,
|
|
changeType: 'CREATE',
|
|
newData: newMember
|
|
})
|
|
console.log(' ✅ 历史记录已创建')
|
|
|
|
// 验证历史记录
|
|
let history = await getMemberHistory(newMember.id)
|
|
console.log(` ✅ 验证: 历史记录数 = ${history.length}, 版本 = ${history[0].version}, 类型 = ${history[0].changeType}`)
|
|
|
|
if (history.length !== 1 || history[0].version !== 1 || history[0].changeType !== 'CREATE') {
|
|
throw new Error('创建成员的历史记录不正确')
|
|
}
|
|
console.log()
|
|
|
|
// 3. 模拟 PATCH /api/trees/[treeId]/members/[memberId] - 更新成员
|
|
console.log('📝 测试 API: PATCH /api/trees/[treeId]/members/[memberId]')
|
|
console.log(' 模拟更新成员...')
|
|
|
|
const existingMember = { ...newMember }
|
|
|
|
const updatedMember = await prisma.familyMember.update({
|
|
where: { id: newMember.id },
|
|
data: {
|
|
fullName: 'API测试(已修改)',
|
|
phone: '13812345678',
|
|
email: 'api-test@example.com',
|
|
bio: 'API 测试用户简介',
|
|
}
|
|
})
|
|
console.log(' ✅ 成员已更新:', updatedMember.fullName)
|
|
|
|
// API 应该调用 recordMemberHistory
|
|
await recordMemberHistory({
|
|
memberId: newMember.id,
|
|
treeId: tree.id,
|
|
changedBy: userId,
|
|
changeType: 'UPDATE',
|
|
oldData: existingMember,
|
|
newData: updatedMember
|
|
})
|
|
console.log(' ✅ 历史记录已创建')
|
|
|
|
// 验证历史记录
|
|
history = await getMemberHistory(newMember.id)
|
|
console.log(` ✅ 验证: 历史记录数 = ${history.length}, 最新版本 = ${history[0].version}`)
|
|
|
|
if (history.length !== 2 || history[0].version !== 2) {
|
|
throw new Error('更新成员的历史记录不正确')
|
|
}
|
|
|
|
// 验证变更字段
|
|
const changes = history[0].changes as Record<string, { old: any, new: any }>
|
|
const expectedFields = ['fullName', 'phone', 'email', 'bio']
|
|
const actualFields = Object.keys(changes)
|
|
|
|
console.log(' ✅ 变更字段:', actualFields.join(', '))
|
|
|
|
for (const field of expectedFields) {
|
|
if (!actualFields.includes(field)) {
|
|
throw new Error(`缺少变更字段: ${field}`)
|
|
}
|
|
}
|
|
console.log()
|
|
|
|
// 4. 测试无变更的更新(不应创建历史记录)
|
|
console.log('📝 测试场景: 无实际变更的更新')
|
|
console.log(' 模拟更新成员(无变更)...')
|
|
|
|
const existingMember2 = { ...updatedMember }
|
|
|
|
// 更新但值不变
|
|
const updatedMember2 = await prisma.familyMember.update({
|
|
where: { id: newMember.id },
|
|
data: {
|
|
fullName: updatedMember.fullName, // 相同的值
|
|
phone: updatedMember.phone, // 相同的值
|
|
}
|
|
})
|
|
|
|
// API 应该调用 recordMemberHistory,但不会创建记录(因为无变更)
|
|
const historyRecord = await recordMemberHistory({
|
|
memberId: newMember.id,
|
|
treeId: tree.id,
|
|
changedBy: userId,
|
|
changeType: 'UPDATE',
|
|
oldData: existingMember2,
|
|
newData: updatedMember2
|
|
})
|
|
|
|
if (historyRecord === null) {
|
|
console.log(' ✅ 正确:无变更时不创建历史记录')
|
|
} else {
|
|
throw new Error('错误:无变更时不应创建历史记录')
|
|
}
|
|
|
|
// 验证历史记录数量未增加
|
|
history = await getMemberHistory(newMember.id)
|
|
if (history.length !== 2) {
|
|
throw new Error('历史记录数量不应增加')
|
|
}
|
|
console.log(` ✅ 验证: 历史记录数仍为 ${history.length}`)
|
|
console.log()
|
|
|
|
// 5. 显示完整的历史记录
|
|
console.log('📋 完整历史记录:')
|
|
console.log('─'.repeat(80))
|
|
for (const record of history.reverse()) {
|
|
console.log(`版本 ${record.version} | ${record.changeType} | ${record.changedAt.toLocaleString('zh-CN')}`)
|
|
console.log(`变更人: ${record.changedBy}`)
|
|
if (record.changes) {
|
|
const changes = record.changes as Record<string, { old: any, new: any }>
|
|
console.log('变更内容:')
|
|
for (const [field, change] of Object.entries(changes)) {
|
|
console.log(` • ${field}: "${change.old}" → "${change.new}"`)
|
|
}
|
|
}
|
|
console.log('─'.repeat(80))
|
|
}
|
|
console.log()
|
|
|
|
// 6. 清理测试数据
|
|
console.log('🧹 清理测试数据...')
|
|
await prisma.memberHistory.deleteMany({
|
|
where: { memberId: newMember.id }
|
|
})
|
|
await prisma.familyMember.delete({
|
|
where: { id: newMember.id }
|
|
})
|
|
console.log('✅ 清理完成')
|
|
console.log()
|
|
|
|
console.log('✅ 所有 API 集成测试通过!')
|
|
console.log()
|
|
console.log('📊 测试总结:')
|
|
console.log(' ✓ POST API 创建成员时正确记录历史')
|
|
console.log(' ✓ PATCH API 更新成员时正确记录历史')
|
|
console.log(' ✓ 只记录实际变更的字段')
|
|
console.log(' ✓ 无变更时不创建历史记录')
|
|
console.log(' ✓ 版本号正确递增')
|
|
console.log(' ✓ 历史记录包含完整的变更信息')
|
|
|
|
} catch (error) {
|
|
console.error('❌ 测试失败:', error)
|
|
throw error
|
|
} finally {
|
|
await prisma.$disconnect()
|
|
}
|
|
}
|
|
|
|
// 运行测试
|
|
testMemberAPIHistory()
|
|
.catch((error) => {
|
|
console.error('测试执行失败:', error)
|
|
process.exit(1)
|
|
})
|