material_manage_system/frontend/src/stores/users.test.js
文睿 张 bcee877278 fix: 物料/用户增删改后列表的搜索关键字被丢弃
写操作后原地重新拉取列表时,search 参数被写死成缺省的空串:搜索框里还显示着
用户输入的关键字,列表却退回全量。用户会把全量列表当成筛选结果,接下来的作废/
删除操作就打在被误认的那一条上。store 层一直有这个缺陷却没被拦住,因为页面
那层没有测试。

修法照 stock.js / approval.js 已有的约定(store 存一份 filters,写操作原地刷新
时取出来用):

- materials.js:编辑/作废/恢复沿用 search 和 status
- users.js:编辑/删除沿用 search
- 新增走反方向,清空筛选并回第 1 页:新建的项不一定匹配当前关键字,沿用搜索
  就看不见它,用户会以为没建成功。物料按 id 倒序,回第 1 页正好能看见
- Materials.vue / Users.vue:新增成功后把搜索框一起清空,否则 store 清了筛选而
  搜索框没清,同样是表里不一

测试补 14 条(两个 store + 两个页面)。全部做过变异验证:把实现改回原样后,
6 条 store 断言和 2 条页面断言确实变红,且只有它们变红。
2026-09-22 14:40:21 +08:00

91 lines
2.6 KiB
JavaScript

import { createPinia, setActivePinia } from 'pinia'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { usersApi } from '../api/users'
import { useUsersStore } from './users'
vi.mock('../api/users', () => ({
usersApi: {
getAll: vi.fn(),
create: vi.fn(),
update: vi.fn(),
delete: vi.fn()
}
}))
describe('users store 的筛选保持', () => {
beforeEach(() => {
setActivePinia(createPinia())
vi.clearAllMocks()
usersApi.getAll.mockResolvedValue({ data: { items: [], total: 0 } })
usersApi.create.mockResolvedValue({ data: {} })
usersApi.update.mockResolvedValue({ data: {} })
usersApi.delete.mockResolvedValue({ data: {} })
})
// 编辑/删除都在原地重新拉取列表,那次拉取必须沿用搜索框里的用户名:否则列表会悄悄
// 退回全量,而搜索框里还显示着用户输入的内容——用户会把全量列表当成筛选结果,接着
// 的删除操作就打在误认的那一条上。
it('编辑用户后刷新列表要沿用当前的搜索关键字', async () => {
const store = useUsersStore()
await store.fetchUsers(2, 'zhangsan')
usersApi.getAll.mockClear()
await store.updateUser(7, { username: 'zhangsan', role_ids: [2] })
expect(usersApi.getAll).toHaveBeenCalledWith({
limit: 20,
offset: 20,
search: 'zhangsan'
})
})
it('删除用户后刷新列表要沿用当前的搜索关键字', async () => {
const store = useUsersStore()
await store.fetchUsers(1, 'zhangsan')
usersApi.getAll.mockClear()
await store.deleteUser(7)
expect(usersApi.getAll).toHaveBeenCalledWith({
limit: 20,
offset: 0,
search: 'zhangsan'
})
})
// 这处刻意与上面相反:新建的用户不一定匹配当前关键字,沿用搜索就看不见它,用户会
// 以为没建成功。
it('新建用户后要清空筛选并回到第 1 页', async () => {
const store = useUsersStore()
await store.fetchUsers(3, 'zhangsan')
usersApi.getAll.mockClear()
await store.createUser({ username: 'lisi', role_ids: [2] })
expect(usersApi.getAll).toHaveBeenCalledWith({
limit: 20,
offset: 0,
search: ''
})
})
// 首次加载没有筛选条件,别把上一次的筛选状态带到新页面上。
it('不带筛选条件地重新查询会清掉旧的筛选状态', async () => {
const store = useUsersStore()
await store.fetchUsers(2, 'zhangsan')
usersApi.getAll.mockClear()
await store.fetchUsers()
expect(usersApi.getAll).toHaveBeenCalledWith({
limit: 20,
offset: 0,
search: ''
})
})
})