gongxiangp2/lib/__tests__/like-transaction.test.ts
chenpei 4e89b57798 feat(upload): optimize upload UI and performance
- Expand batch upload list area and optimize preview image layout
- Improve upload speed tracking and display (server-side & client-side)
- Reduce network detection log noise
- Optimize Docker build process (caching, env validation)
- Add shadow environment deployment support
2026-01-28 15:07:50 +08:00

107 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* R46修复测试:点赞操作事务保护
*
* 验证:
* 1. 点赞/取消点赞代码中使用了 $transaction
* 2. 删除记录和更新计数在同一事务中
*/
describe('R46: 点赞操作事务保护测试', () => {
test('点赞路由应该使用事务保护', async () => {
const fs = require('fs')
const path = require('path')
const filePath = path.join(__dirname, '../../app/api/materials/like/route.ts')
if (!fs.existsSync(filePath)) {
console.log('跳过测试:文件不存在', filePath)
return
}
const content = fs.readFileSync(filePath, 'utf-8')
// 检查是否使用了 $transaction
expect(content).toContain('$transaction')
})
test('取消点赞应该在事务中执行删除和更新', async () => {
const fs = require('fs')
const path = require('path')
const filePath = path.join(__dirname, '../../app/api/materials/like/route.ts')
if (!fs.existsSync(filePath)) {
console.log('跳过测试:文件不存在', filePath)
return
}
const content = fs.readFileSync(filePath, 'utf-8')
// 检查取消点赞部分是否包含事务
// 应该看到 tx.materialLike.delete 和 tx.material.update 在同一个 $transaction 块中
expect(content).toContain('tx.materialLike.delete')
expect(content).toContain('tx.material.update')
})
test('点赞应该在事务中执行创建和更新', async () => {
const fs = require('fs')
const path = require('path')
const filePath = path.join(__dirname, '../../app/api/materials/like/route.ts')
if (!fs.existsSync(filePath)) {
console.log('跳过测试:文件不存在', filePath)
return
}
const content = fs.readFileSync(filePath, 'utf-8')
// 检查点赞部分是否包含事务
expect(content).toContain('tx.materialLike.create')
})
test('不应该有独立的 prisma.materialLike 和 prisma.material 调用(应该都用 tx)', async () => {
const fs = require('fs')
const path = require('path')
const filePath = path.join(__dirname, '../../app/api/materials/like/route.ts')
if (!fs.existsSync(filePath)) {
console.log('跳过测试:文件不存在', filePath)
return
}
const content = fs.readFileSync(filePath, 'utf-8')
// 统计事务内外的调用
const lines = content.split('\n')
let inTransaction = false
let independentMaterialLikeWrite = false
let independentMaterialUpdate = false
for (const line of lines) {
if (line.includes('$transaction')) {
inTransaction = true
}
// 检查是否有不在事务中的写操作
// 排除 findFirst(查询操作可以不在事务中)
if (!inTransaction) {
if (line.includes('prisma.materialLike.delete') ||
line.includes('prisma.materialLike.create')) {
independentMaterialLikeWrite = true
}
if (line.includes('prisma.material.update') &&
(line.includes('increment') || line.includes('decrement'))) {
independentMaterialUpdate = true
}
}
}
// 不应该有独立的写操作
expect(independentMaterialLikeWrite).toBe(false)
expect(independentMaterialUpdate).toBe(false)
})
})