mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-15 11:14:31 +08:00
- 在表概览及新旧侧栏右键菜单接入复制整表入口与确认、进度和刷新反馈 - 按 source_copyN 原子创建目标表并复制列、索引、默认值及全部数据 - 处理 PostgreSQL 生成列、identity/serial 序列校准与失败清理 - 限定安全数据源与连接保护策略,阻止分区表、RLS 及引用型存储引擎 - 加固 MySQL/PostgreSQL 元数据标识符处理并补齐六语种文案 - 增加后端、能力矩阵、菜单接线和国际化回归测试
89 lines
2.5 KiB
TypeScript
89 lines
2.5 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||
|
||
import { setCurrentLanguage } from '../i18n';
|
||
import { confirmCopyTable } from './tableCopyAction';
|
||
|
||
const mocks = vi.hoisted(() => ({
|
||
confirm: vi.fn(),
|
||
hide: vi.fn(),
|
||
loading: vi.fn(),
|
||
success: vi.fn(),
|
||
warning: vi.fn(),
|
||
error: vi.fn(),
|
||
copyTable: vi.fn(),
|
||
}));
|
||
|
||
vi.mock('./common/ResizableDraggableModal', () => ({
|
||
default: { confirm: mocks.confirm },
|
||
}));
|
||
|
||
vi.mock('antd', () => ({
|
||
message: {
|
||
loading: mocks.loading,
|
||
success: mocks.success,
|
||
warning: mocks.warning,
|
||
error: mocks.error,
|
||
},
|
||
}));
|
||
|
||
describe('confirmCopyTable', () => {
|
||
beforeEach(() => {
|
||
vi.clearAllMocks();
|
||
setCurrentLanguage('zh-CN');
|
||
mocks.loading.mockReturnValue(mocks.hide);
|
||
(globalThis as any).go = {
|
||
app: { App: { CopyTable: mocks.copyTable } },
|
||
};
|
||
});
|
||
|
||
it('confirms before copying and refreshes with the backend-generated table name', async () => {
|
||
const onSuccess = vi.fn();
|
||
const config = { type: 'mysql' };
|
||
mocks.copyTable.mockResolvedValue({
|
||
success: true,
|
||
data: 'orders_copy2',
|
||
});
|
||
|
||
confirmCopyTable({
|
||
config,
|
||
dbName: 'sales',
|
||
sourceSchemaName: 'reporting',
|
||
sourceTableName: 'orders',
|
||
onSuccess,
|
||
});
|
||
|
||
expect(mocks.confirm).toHaveBeenCalledOnce();
|
||
const options = mocks.confirm.mock.calls[0][0];
|
||
expect(options.title).toBe('复制整表');
|
||
expect(options.content).toContain('orders');
|
||
expect(options.content).toContain('orders_copy1');
|
||
expect(options.content).toContain('外键、触发器和授权不会复制');
|
||
|
||
await options.onOk();
|
||
|
||
expect(mocks.copyTable).toHaveBeenCalledWith(config, 'sales', 'reporting', 'orders');
|
||
expect(mocks.success).toHaveBeenCalledWith('整表复制成功:orders_copy2');
|
||
expect(onSuccess).toHaveBeenCalledWith('orders_copy2');
|
||
expect(mocks.hide).toHaveBeenCalledOnce();
|
||
});
|
||
|
||
it('keeps the confirmation open and reports backend failures', async () => {
|
||
mocks.copyTable.mockResolvedValue({
|
||
success: false,
|
||
message: 'copy failed',
|
||
});
|
||
|
||
confirmCopyTable({
|
||
config: { type: 'mysql' },
|
||
dbName: 'sales',
|
||
sourceTableName: 'orders',
|
||
});
|
||
|
||
const options = mocks.confirm.mock.calls[0][0];
|
||
await expect(options.onOk()).rejects.toThrow('copy failed');
|
||
expect(mocks.error).toHaveBeenCalledWith('整表复制失败:copy failed');
|
||
expect(mocks.success).not.toHaveBeenCalled();
|
||
expect(mocks.hide).toHaveBeenCalledOnce();
|
||
});
|
||
});
|