test: 添加 background 单元测试与边界情况处理

- 新增 entrypoints/__tests__/background.test.ts (12个测试用例)
- 超长文本截断限制 (>10000字符)
- Base64 内联图片拦截并返回错误提示
- 更新 parseContextMenuClick 返回 ParseResult 格式
- 更新测试匹配新的返回格式
- lint/typecheck/test 全部通过 (579个测试)
This commit is contained in:
雨霖铃
2026-05-20 20:54:51 +08:00
parent 3b98c9438e
commit c1890960ea
4 changed files with 278 additions and 29 deletions
+61 -17
View File
@@ -3,6 +3,7 @@ import {
CONTEXT_MENU_CONFIGS,
createAllContextMenus,
parseContextMenuClick,
MAX_PAYLOAD_LENGTH,
} from '@/utils/contextMenu';
describe('contextMenu', () => {
@@ -96,19 +97,33 @@ describe('contextMenu', () => {
const result = parseContextMenuClick('qrCode-image', info);
expect(result).toEqual({
featureKey: 'qrCode',
payload: 'https://example.com/image.png',
success: true,
data: { featureKey: 'qrCode', payload: 'https://example.com/image.png' },
});
});
it('当点击 qrCode-image 菜单但没有 srcUrl 时应返回空字符串', () => {
it('当图片为 Base64 内联图时应返回错误', () => {
const info = createMockOnClickData({
srcUrl:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
});
const result = parseContextMenuClick('qrCode-image', info);
expect(result).toEqual({
success: false,
error: '无法识别 Base64 内联图片,请使用图片文件 URL',
});
});
it('当点击 qrCode-image 菜单但没有 srcUrl 时应返回成功', () => {
const info = createMockOnClickData({});
const result = parseContextMenuClick('qrCode-image', info);
expect(result).toEqual({
featureKey: 'qrCode',
payload: '',
success: true,
data: { featureKey: 'qrCode', payload: '' },
});
});
@@ -120,8 +135,8 @@ describe('contextMenu', () => {
const result = parseContextMenuClick('qrCode-page', info);
expect(result).toEqual({
featureKey: 'qrCode',
payload: 'https://example.com/page',
success: true,
data: { featureKey: 'qrCode', payload: 'https://example.com/page' },
});
});
@@ -133,8 +148,8 @@ describe('contextMenu', () => {
const result = parseContextMenuClick('jwt', info);
expect(result).toEqual({
featureKey: 'jwt',
payload: 'selected text',
success: true,
data: { featureKey: 'jwt', payload: 'selected text' },
});
});
@@ -146,8 +161,8 @@ describe('contextMenu', () => {
const result = parseContextMenuClick('timestamp', info);
expect(result).toEqual({
featureKey: 'timestamp',
payload: '1234567890',
success: true,
data: { featureKey: 'timestamp', payload: '1234567890' },
});
});
@@ -159,19 +174,22 @@ describe('contextMenu', () => {
const result = parseContextMenuClick('storageCleaner', info);
expect(result).toEqual({
featureKey: 'storageCleaner',
payload: 'https://example.com',
success: true,
data: { featureKey: 'storageCleaner', payload: 'https://example.com' },
});
});
it('当没有 selectionText 和 pageUrl 时应返回 null', () => {
it('当没有 selectionText 和 pageUrl 时应返回错误', () => {
const info = createMockOnClickData({
pageUrl: undefined,
});
const result = parseContextMenuClick('someMenu', info);
expect(result).toBeNull();
expect(result).toEqual({
success: false,
error: '无法获取有效数据',
});
});
it('selectionText 优先于 pageUrl', () => {
@@ -183,8 +201,34 @@ describe('contextMenu', () => {
const result = parseContextMenuClick('jwt', info);
expect(result).toEqual({
featureKey: 'jwt',
payload: 'selected text',
success: true,
data: { featureKey: 'jwt', payload: 'selected text' },
});
});
it('当文本超过最大长度限制时应截断', () => {
const longText = 'a'.repeat(MAX_PAYLOAD_LENGTH + 1000);
const info = createMockOnClickData({
selectionText: longText,
});
const result = parseContextMenuClick('textStatistics', info);
expect(result.success).toBe(true);
expect(result.data?.payload.length).toBe(MAX_PAYLOAD_LENGTH);
});
it('当文本未超过最大长度限制时应保持原样', () => {
const shortText = 'short text';
const info = createMockOnClickData({
selectionText: shortText,
});
const result = parseContextMenuClick('textStatistics', info);
expect(result).toEqual({
success: true,
data: { featureKey: 'textStatistics', payload: 'short text' },
});
});
});
+36 -10
View File
@@ -12,8 +12,16 @@ export interface ContextMenuClickedInfo {
payload: string;
}
export interface ParseResult {
success: boolean;
data?: ContextMenuClickedInfo;
error?: string;
}
const PARENT_MENU_ID = 'testing-tools-parent';
export const MAX_PAYLOAD_LENGTH = 10000;
export const CONTEXT_MENU_CONFIGS: ContextMenuItemConfig[] = [
{
id: PARENT_MENU_ID,
@@ -78,36 +86,54 @@ export function createAllContextMenus(): void {
export function parseContextMenuClick(
menuItemId: string,
info: chrome.contextMenus.OnClickData,
): ContextMenuClickedInfo | null {
): ParseResult {
const featureKey = menuItemId as PageType;
if (menuItemId === 'qrCode-image') {
const srcUrl = info.srcUrl || '';
if (srcUrl.startsWith('data:image/')) {
return {
success: false,
error: '无法识别 Base64 内联图片,请使用图片文件 URL',
};
}
return {
featureKey: 'qrCode',
payload: info.srcUrl || '',
success: true,
data: { featureKey: 'qrCode', payload: srcUrl },
};
}
if (menuItemId === 'qrCode-page') {
return {
featureKey: 'qrCode',
payload: info.pageUrl || '',
success: true,
data: { featureKey: 'qrCode', payload: info.pageUrl || '' },
};
}
if (info.selectionText) {
const text = info.selectionText;
if (text.length > MAX_PAYLOAD_LENGTH) {
return {
success: true,
data: { featureKey, payload: text.substring(0, MAX_PAYLOAD_LENGTH) },
};
}
return {
featureKey,
payload: info.selectionText,
success: true,
data: { featureKey, payload: text },
};
}
if (info.pageUrl) {
return {
featureKey,
payload: info.pageUrl,
success: true,
data: { featureKey, payload: info.pageUrl },
};
}
return null;
return { success: false, error: '无法获取有效数据' };
}