mirror of
https://github.com/insistence/RuoYi-Vue3-FastAPI.git
synced 2026-10-15 05:19:14 +00:00
* feat: 支持 v2 插件、原生扩展与签名发布 * fix: 修复测试 * feat: 增强宿主 SDK、运行观测与制品维护能力 * feat: 增强文件传输、配置观测与本地开发能力 * feat: 支持 SSE 实时事件流并完善开发脚手架 * feat: 完善长连接鉴权复核与关闭回收 * feat: 增强生命周期与任务关闭可靠性 * feat: 收紧健康检查契约并补齐前端与真实网络验收 * feat: 增加SDK溯源与离线更新工具并验证跨版本兼容 * feat: 增加持久化业务示例与受控 Python 交付 * feat: 增加统一运行诊断与多worker状态观测 * feat: 增加固定目标发布等待与自动验收 * fix: 修复多环境插件部署前缀与代理配置不一致 * fix: 修复测试
93 lines
3.4 KiB
JavaScript
93 lines
3.4 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
import { createMockTaskApi } from '../dev/mockRequest.js'
|
|
|
|
const draft = {
|
|
title: '测试任务',
|
|
description: '保留完整说明',
|
|
status: 'todo',
|
|
priority: 'normal',
|
|
}
|
|
const call = (api, method, path, extra = {}) =>
|
|
api.request({
|
|
method,
|
|
url: `/apps/task_demo/api/${path}`,
|
|
...extra,
|
|
})
|
|
|
|
test('内存数据支持分页、筛选、完整 CRUD 和响应副本隔离', async () => {
|
|
const api = createMockTaskApi({ getDelay: () => 0 })
|
|
const first = await call(api, 'get', 'tasks', {
|
|
params: { page: 1, pageSize: 10 },
|
|
})
|
|
const second = await call(api, 'get', 'tasks', {
|
|
params: { page: 2, pageSize: 10 },
|
|
})
|
|
assert.equal(first.total, 12)
|
|
assert.equal(first.items.length, 10)
|
|
assert.equal(second.items.length, 2)
|
|
assert.equal(new Set([...first.items, ...second.items].map((task) => task.id)).size, 12)
|
|
const created = await call(api, 'post', 'tasks', { data: draft })
|
|
assert.equal(created.title, draft.title)
|
|
created.title = '修改响应不能污染存储'
|
|
assert.equal((await call(api, 'get', `tasks/${created.id}`)).title, draft.title)
|
|
const updated = await call(api, 'put', `tasks/${created.id}`, {
|
|
data: { ...draft, status: 'done', priority: 'high' },
|
|
})
|
|
assert.equal(updated.createdAt, created.createdAt)
|
|
const done = await call(api, 'get', 'tasks', { params: { status: 'done' } })
|
|
assert.ok(done.items.every((task) => task.status === 'done'))
|
|
assert.ok(done.items.some((task) => task.id === created.id && task.priority === 'high'))
|
|
assert.deepEqual(await call(api, 'delete', `tasks/${created.id}`), {
|
|
deleted: true,
|
|
})
|
|
await assert.rejects(call(api, 'get', `tasks/${created.id}`), /不存在/)
|
|
})
|
|
|
|
test('只读权限在请求层拒绝所有写操作并保留数据', async () => {
|
|
let writable = true
|
|
const api = createMockTaskApi({
|
|
getDelay: () => 0,
|
|
getCanWrite: () => writable,
|
|
})
|
|
const task = await call(api, 'post', 'tasks', { data: draft })
|
|
writable = false
|
|
assert.equal((await call(api, 'get', 'info')).canWrite, false)
|
|
assert.equal((await call(api, 'get', 'tasks')).canWrite, false)
|
|
for (const [method, path] of [
|
|
['post', 'tasks'],
|
|
['put', `tasks/${task.id}`],
|
|
['delete', `tasks/${task.id}`],
|
|
]) {
|
|
await assert.rejects(call(api, method, path, { data: draft }), /写入权限/)
|
|
}
|
|
assert.equal((await call(api, 'get', 'tasks')).total, 13)
|
|
assert.equal((await call(api, 'get', `tasks/${task.id}`)).title, draft.title)
|
|
})
|
|
|
|
test('失败、取消及无效输入不会产生写入副作用', async () => {
|
|
let fail = true
|
|
const api = createMockTaskApi({ getDelay: () => 10, shouldFail: () => fail })
|
|
await assert.rejects(call(api, 'post', 'tasks', { data: draft }), /模拟请求失败/)
|
|
fail = false
|
|
const controller = new AbortController()
|
|
const pending = call(api, 'post', 'tasks', {
|
|
data: draft,
|
|
signal: controller.signal,
|
|
})
|
|
controller.abort()
|
|
await assert.rejects(pending, /取消/)
|
|
for (const data of [
|
|
{ ...draft, title: ' ' },
|
|
{ ...draft, description: 'x'.repeat(501) },
|
|
{ ...draft, status: 'invalid' },
|
|
]) {
|
|
await assert.rejects(call(api, 'post', 'tasks', { data }))
|
|
}
|
|
assert.equal((await call(api, 'get', 'tasks')).total, 12)
|
|
api.clear()
|
|
assert.equal((await call(api, 'get', 'tasks')).total, 0)
|
|
api.reset()
|
|
assert.equal((await call(api, 'get', 'tasks')).total, 12)
|
|
})
|