- 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
107 lines
3.3 KiB
TypeScript
107 lines
3.3 KiB
TypeScript
/**
|
||
* 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)
|
||
})
|
||
})
|