57ea4d9858
- **docs**: 完善组件注释、README 目录结构及 AGENTS.md 文档。 - **refactor**: - 提取通用 `PageHeader`、`Button`、`DashboardCard` 及 `ErrorBoundary` 组件。 - 重构消息通信机制,采用 `@webext-core/messaging` 实现类型安全。 - 将全局通知系统重构为 `SnackbarProvider` (后合并至 `GlobalSnackbar`)。 - 迁移样式系统至 MUI 主题,移除冗余 CSS。 - 优化路由配置,支持独立标签页模式及页面懒加载。 - 移除未使用文件、URL 工具及表单映射相关功能。 - **feat**: - 新增配置导出功能(JSON)及状态提示。 - 新增侧边栏状态变化通知机制。 - 新增文本统计及 JWT 解析工具。 - 优化二维码生成与解析逻辑,换用更轻量的 `qrious` 和 `qr-scanner`。 - 增强高亮器功能,支持闪烁效果及 Shadow DOM 穿透。 - **style**: 优化仪表盘响应式网格布局及 UI 细节。 - **fix**: 修复 `useStorageState` 依赖缺失及路由初始化性能问题。 - **test**: 更新单元测试以覆盖新增的工具函数及功能特性。
127 lines
4.4 KiB
TypeScript
127 lines
4.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
FEATURES,
|
|
getAllFeatureKeys,
|
|
getDefaultPageOrder,
|
|
getDefaultVisibleFeatureKeys,
|
|
getFeatureByKey,
|
|
} from '../features';
|
|
|
|
describe('features', () => {
|
|
describe('FEATURES', () => {
|
|
it('should have 6 features defined', () => {
|
|
expect(FEATURES).toHaveLength(6);
|
|
});
|
|
|
|
it('should have all required properties for each feature', () => {
|
|
FEATURES.forEach((feature) => {
|
|
expect(feature).toHaveProperty('key');
|
|
expect(feature).toHaveProperty('label');
|
|
expect(feature).toHaveProperty('description');
|
|
expect(feature).toHaveProperty('defaultVisible');
|
|
expect(feature).toHaveProperty('components');
|
|
expect(typeof feature.key).toBe('string');
|
|
expect(typeof feature.label).toBe('string');
|
|
expect(typeof feature.description).toBe('string');
|
|
expect(typeof feature.defaultVisible).toBe('boolean');
|
|
expect(typeof feature.components).toBe('object');
|
|
expect(feature.components).toHaveProperty('popup');
|
|
expect(feature.components).toHaveProperty('sidepanel');
|
|
expect(feature.components).toHaveProperty('tab');
|
|
|
|
// Optional UI properties for non-hidden features
|
|
if (feature.key !== 'dashboard') {
|
|
expect(feature).toHaveProperty('icon');
|
|
expect(feature).toHaveProperty('themeColor');
|
|
expect(typeof feature.themeColor).toBe('string');
|
|
}
|
|
});
|
|
});
|
|
|
|
it('should have unique keys for each feature', () => {
|
|
const keys = FEATURES.map((f) => f.key);
|
|
const uniqueKeys = new Set(keys);
|
|
expect(uniqueKeys.size).toBe(keys.length);
|
|
});
|
|
});
|
|
|
|
describe('getFeatureByKey', () => {
|
|
it('should return dashboard feature', () => {
|
|
const feature = getFeatureByKey('dashboard');
|
|
expect(feature).toBeDefined();
|
|
expect(feature?.key).toBe('dashboard');
|
|
expect(feature?.label).toBe('Dashboard');
|
|
});
|
|
|
|
it('should return timestamp feature', () => {
|
|
const feature = getFeatureByKey('timestamp');
|
|
expect(feature).toBeDefined();
|
|
expect(feature?.key).toBe('timestamp');
|
|
expect(feature?.label).toBe('时间戳');
|
|
expect(feature?.themeColor).toBeDefined();
|
|
});
|
|
|
|
it('should return storageCleaner feature', () => {
|
|
const feature = getFeatureByKey('storageCleaner');
|
|
expect(feature).toBeDefined();
|
|
expect(feature?.key).toBe('storageCleaner');
|
|
expect(feature?.label).toBe('存储清理');
|
|
});
|
|
|
|
it('should return undefined for invalid key', () => {
|
|
const feature = getFeatureByKey('invalid' as any);
|
|
expect(feature).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('getDefaultVisibleFeatureKeys', () => {
|
|
it('should return only visible features', () => {
|
|
const visibleKeys = getDefaultVisibleFeatureKeys();
|
|
visibleKeys.forEach((key) => {
|
|
const feature = getFeatureByKey(key);
|
|
expect(feature?.defaultVisible).toBe(true);
|
|
});
|
|
});
|
|
|
|
it('should include dashboard, timestamp, storageCleaner, qrCode', () => {
|
|
const visibleKeys = getDefaultVisibleFeatureKeys();
|
|
expect(visibleKeys).toContain('dashboard');
|
|
expect(visibleKeys).toContain('timestamp');
|
|
expect(visibleKeys).toContain('storageCleaner');
|
|
expect(visibleKeys).toContain('qrCode');
|
|
});
|
|
});
|
|
|
|
describe('getAllFeatureKeys', () => {
|
|
it('should return all feature keys', () => {
|
|
const allKeys = getAllFeatureKeys();
|
|
expect(allKeys).toHaveLength(6);
|
|
expect(allKeys).toContain('dashboard');
|
|
expect(allKeys).toContain('timestamp');
|
|
expect(allKeys).toContain('storageCleaner');
|
|
expect(allKeys).toContain('qrCode');
|
|
expect(allKeys).toContain('textStatistics');
|
|
expect(allKeys).toContain('jwt');
|
|
});
|
|
});
|
|
|
|
describe('getDefaultPageOrder', () => {
|
|
it('should exclude dashboard from page order', () => {
|
|
const pageOrder = getDefaultPageOrder();
|
|
expect(pageOrder).not.toContain('dashboard');
|
|
});
|
|
|
|
it('should include timestamp, storageCleaner, qrCode in page order', () => {
|
|
const pageOrder = getDefaultPageOrder();
|
|
expect(pageOrder).toContain('timestamp');
|
|
expect(pageOrder).toContain('storageCleaner');
|
|
expect(pageOrder).toContain('qrCode');
|
|
});
|
|
|
|
it('should have 5 items in page order', () => {
|
|
const pageOrder = getDefaultPageOrder();
|
|
expect(pageOrder).toHaveLength(5);
|
|
});
|
|
});
|
|
});
|