138 lines
5.0 KiB
JavaScript
138 lines
5.0 KiB
JavaScript
/**
|
|
* 回归用例:菜单管理 - 保存时必须带上派生的树字段,并按 s_i18n 真实主键读写多语言。
|
|
*
|
|
* 1) s_menu.b_path 为 not null 且无默认值(b_depth / b_xh / b_canuse 才有默认值),
|
|
* 请求里缺 b_path 会直接失败:
|
|
* Cannot insert the value NULL into column 'b_path', table 'FMS.dbo.s_menu'
|
|
* 另外新增草稿的 b_id 是本地临时负数 id(仅用于树 key),保存时必须换成录入的
|
|
* 菜单编码后重算路径,否则会把 /-1/ 这类临时路径写进库。
|
|
*
|
|
* 2) s_i18n 主键为 (b_key, b_locale),表内没有 b_id / b_module_id。
|
|
* 菜单多语言行必须按 b_key = menu.{菜单编码} 定位,否则加载会报无效列名、
|
|
* 保存会报「主键字段不存在: s_i18n.b_id」。
|
|
*/
|
|
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
import { flushPromises } from '@vue/test-utils'
|
|
import { setActivePinia } from 'pinia'
|
|
import MenuManagement from '@/views/module/menu-management/index.vue'
|
|
import { useI18nStore } from '@/stores/i18n'
|
|
import { mountPage } from '../helpers/app.js'
|
|
|
|
vi.mock('@/services/api', () => ({
|
|
loadDataApi: vi.fn(),
|
|
saveObjectApi: vi.fn(() => Promise.resolve({ code: 0, success: true })),
|
|
nextIdApi: vi.fn(() => Promise.resolve({ data: 9001, code: 0, success: true })),
|
|
describeApi: vi.fn(() => Promise.resolve({ data: [], code: 0, success: true })),
|
|
}))
|
|
|
|
vi.mock('@/components/ui/message/message-manager.js', () => {
|
|
const m = { success: vi.fn(), error: vi.fn(), warning: vi.fn(), info: vi.fn() }
|
|
return { Message: m, default: m }
|
|
})
|
|
|
|
import { loadDataApi, saveObjectApi } from '@/services/api'
|
|
|
|
const systemMenu = {
|
|
b_id: 'system',
|
|
b_parent_id: null,
|
|
b_depth: 0,
|
|
b_path: '/system/',
|
|
b_name: '系统管理',
|
|
b_i18n: 'menu.system',
|
|
b_menu_type: 'directory',
|
|
b_route: null,
|
|
b_icon: null,
|
|
b_xh: 10,
|
|
b_canuse: 1,
|
|
}
|
|
|
|
const languages = [
|
|
{ b_id: 'zh-CN', b_name: '简体中文', b_canuse: 1, b_default: 1, b_xh: 10 },
|
|
{ b_id: 'en-US', b_name: '英文', b_canuse: 1, b_default: 0, b_xh: 20 },
|
|
]
|
|
|
|
const i18nRows = [{ b_key: 'menu.system', b_locale: 'en-US', b_value: 'System', b_canuse: 1 }]
|
|
|
|
beforeEach(() => {
|
|
loadDataApi.mockReset()
|
|
saveObjectApi.mockClear()
|
|
loadDataApi.mockImplementation((view) => {
|
|
if (view === 's_menu') return Promise.resolve({ data: [systemMenu] })
|
|
if (view === 's_i18n') return Promise.resolve({ data: i18nRows })
|
|
if (view === 's_i18n_type') return Promise.resolve({ data: languages })
|
|
return Promise.resolve({ data: [] })
|
|
})
|
|
})
|
|
|
|
/** 取出最近一次保存请求里的指定表请求 */
|
|
function lastRequestOf(table) {
|
|
const requests = saveObjectApi.mock.calls.at(-1)[0]
|
|
return requests.find((request) => request.table === table)
|
|
}
|
|
|
|
describe('菜单管理:新增菜单的派生树字段', () => {
|
|
it('新增根菜单按最终菜单编码写入 b_path / b_depth', async () => {
|
|
const { wrapper } = await mountPage(MenuManagement)
|
|
await flushPromises()
|
|
|
|
await wrapper.vm.addMenu(null, 'page')
|
|
await flushPromises()
|
|
wrapper.vm.maindata.b_id = 'home'
|
|
wrapper.vm.maindata.b_name = '首页'
|
|
wrapper.vm.maindata.b_route = '/dashboard'
|
|
await wrapper.vm.handleSave()
|
|
|
|
const request = lastRequestOf('s_menu')
|
|
expect(request.inserts).toHaveLength(1)
|
|
expect(request.inserts[0].b_id).toBe('home')
|
|
expect(request.inserts[0].b_path).toBe('/home/')
|
|
expect(request.inserts[0].b_depth).toBe(0)
|
|
})
|
|
|
|
it('新增子菜单按父级路径拼出 b_path 并递增 b_depth', async () => {
|
|
const { wrapper } = await mountPage(MenuManagement)
|
|
await flushPromises()
|
|
|
|
await wrapper.vm.addMenu('system', 'page')
|
|
await flushPromises()
|
|
wrapper.vm.maindata.b_id = 'user'
|
|
wrapper.vm.maindata.b_name = '用户管理'
|
|
wrapper.vm.maindata.b_route = '/system/user'
|
|
await wrapper.vm.handleSave()
|
|
|
|
const request = lastRequestOf('s_menu')
|
|
expect(request.inserts[0].b_path).toBe('/system/user/')
|
|
expect(request.inserts[0].b_depth).toBe(1)
|
|
})
|
|
})
|
|
|
|
describe('菜单管理:多语言按 s_i18n 真实主键 (b_key, b_locale) 读写', () => {
|
|
it('加载按 b_key 精确匹配,保存以 (b_key, b_locale) 为键且不写不存在的列', async () => {
|
|
const { wrapper, pinia } = await mountPage(MenuManagement)
|
|
setActivePinia(pinia)
|
|
await useI18nStore().loadLanguages()
|
|
await flushPromises()
|
|
|
|
wrapper.vm.menuSelectedId = 'system'
|
|
await flushPromises()
|
|
|
|
expect(loadDataApi).toHaveBeenCalledWith('s_i18n', "b_key = N'menu.system'", 'b_locale ASC')
|
|
expect(wrapper.vm.i18n_values['en-US']).toBe('System')
|
|
|
|
wrapper.vm.setI18nValue('en-US', 'System 2')
|
|
await wrapper.vm.handleSave()
|
|
|
|
const request = lastRequestOf('s_i18n')
|
|
expect(request.key_field).toBe('b_key,b_locale')
|
|
expect(request.updates).toHaveLength(1)
|
|
expect(request.updates[0]).toMatchObject({
|
|
b_key: 'menu.system',
|
|
b_locale: 'en-US',
|
|
b_value: 'System 2',
|
|
b_canuse: 1,
|
|
})
|
|
expect(request.updates[0].b_id).toBeUndefined()
|
|
expect(request.updates[0].b_module_id).toBeUndefined()
|
|
})
|
|
})
|