cloud-drive-renamer/tests/unit/conflict-detector.test.ts
Zain 1176d08224 feat(onedrive): 新增 OneDrive 个人版支持,更新第 13 个平台文案与键盘隔离
新增 OneDrive 个人版适配器、MAIN 桥接、名称校验与冲突检测、目录身份与分页遍历。同步更新三语简介、商店素材、仓库描述及
manifest 域名注册。修复面板键盘冒泡至宿主页面的隔离与工具栏 Escape 作用域。修正 OneDrive 同步结果语义为手动刷新提示,
避免误报同步失败。补全对应单测与浏览器验收脚本。
2026-09-27 17:31:44 +08:00

90 行
2.8 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
buildConflictDetails,
checkBatchConflicts,
ConflictResolution,
ConflictType,
} from '../../src/core/conflict-detector';
import type { FileItem } from '../../src/types/platform';
const files: FileItem[] = [
{ id: '1', name: 'old-a.txt', ext: '.txt', parentId: 'root', size: 1, mtime: 1 },
{ id: '2', name: 'old-b.txt', ext: '.txt', parentId: 'root', size: 1, mtime: 1 },
{ id: '3', name: 'old-c.txt', ext: '.txt', parentId: 'root', size: 1, mtime: 1 },
];
describe('conflict-detector helpers', () => {
it('supports platform-scoped filename normalization for case-insensitive drives', () => {
const normalized = checkBatchConflicts(files.slice(0, 2), ['Same.txt', 'same.TXT'], (name) => name.toLowerCase());
expect(normalized.get('1')?.type).toBe(ConflictType.DUPLICATE_IN_BATCH);
expect(normalized.get('2')?.type).toBe(ConflictType.DUPLICATE_IN_BATCH);
const unchangedDefault = checkBatchConflicts(files.slice(0, 2), ['Same.txt', 'same.TXT']);
expect(unchangedDefault.get('1')?.hasConflict).toBe(false);
expect(unchangedDefault.get('2')?.hasConflict).toBe(false);
});
it('builds conflict detail rows for duplicate and existing-name conflicts', () => {
const newNames = ['same.txt', 'same.txt', 'taken.txt'];
const conflicts = new Map([
[
'1',
{
type: ConflictType.DUPLICATE_IN_BATCH,
hasConflict: true,
conflictingName: 'same.txt',
conflictingFiles: ['old-a.txt', 'old-b.txt'],
},
],
[
'2',
{
type: ConflictType.DUPLICATE_IN_BATCH,
hasConflict: true,
conflictingName: 'same.txt',
conflictingFiles: ['old-a.txt', 'old-b.txt'],
},
],
[
'3',
{
type: ConflictType.NAME_EXISTS,
hasConflict: true,
conflictingName: 'taken.txt',
},
],
]);
expect(buildConflictDetails(files, newNames, conflicts)).toEqual([
{
fileId: '1',
originalName: 'old-a.txt',
targetName: 'same.txt',
type: ConflictType.DUPLICATE_IN_BATCH,
conflictingFiles: ['old-a.txt', 'old-b.txt'],
},
{
fileId: '2',
originalName: 'old-b.txt',
targetName: 'same.txt',
type: ConflictType.DUPLICATE_IN_BATCH,
conflictingFiles: ['old-a.txt', 'old-b.txt'],
},
{
fileId: '3',
originalName: 'old-c.txt',
targetName: 'taken.txt',
type: ConflictType.NAME_EXISTS,
conflictingFiles: [],
},
]);
});
it('exposes only auto-number and skip as executable conflict strategies', () => {
expect(Object.values(ConflictResolution)).toEqual([
ConflictResolution.AUTO_NUMBER,
ConflictResolution.SKIP,
]);
});
});