mirror of
https://github.com/yaklang/yaklang-chrome-extension.git
synced 2026-09-21 19:10:41 +08:00
57 lines
2.7 KiB
TypeScript
57 lines
2.7 KiB
TypeScript
import { vi, describe, expect, it } from 'vitest';
|
|
|
|
vi.mock('wxt/browser', () => ({ browser: { declarativeNetRequest: {} } }));
|
|
|
|
import {
|
|
buildUserAgentDnrRules, resolveUserAgent, userAgentHostname, validateUserAgent,
|
|
} from './user-agent';
|
|
import { BUILTIN_USER_AGENT_PROFILES } from './user-agent-profiles';
|
|
import type { UserAgentAssignment, UserAgentProfile } from '@/types/models';
|
|
|
|
const assignment: UserAgentAssignment = {
|
|
id: 'assignment-1', hostname: 'app.example.test', profileId: 'chrome-windows', createdAt: 1, updatedAt: 2,
|
|
};
|
|
|
|
describe('User-Agent site assignments', () => {
|
|
it('compiles one real request-header rule for each hostname', () => {
|
|
const [rule] = buildUserAgentDnrRules([assignment]);
|
|
expect(rule.condition.urlFilter).toBe('||app.example.test^');
|
|
expect(rule.condition.resourceTypes).toContain('websocket');
|
|
expect(rule.action).toMatchObject({ requestHeaders: [{ header: 'user-agent', operation: 'set' }] });
|
|
});
|
|
|
|
it('deduplicates a hostname and ignores missing profiles', () => {
|
|
const rules = buildUserAgentDnrRules([
|
|
assignment,
|
|
{ ...assignment, id: 'assignment-2', profileId: 'safari-iphone', updatedAt: 3 },
|
|
{ ...assignment, id: 'missing', hostname: 'missing.example.test', profileId: 'missing' },
|
|
]);
|
|
expect(rules).toHaveLength(1);
|
|
expect(rules[0].action).toMatchObject({
|
|
requestHeaders: [{ value: BUILTIN_USER_AGENT_PROFILES.find((item) => item.id === 'safari-iphone')!.userAgent }],
|
|
});
|
|
});
|
|
|
|
it('resolves the effective profile for the current URL', () => {
|
|
expect(resolveUserAgent('https://app.example.test/path', [assignment], [], 'Browser/Default'))
|
|
.toMatchObject({ hostname: 'app.example.test', mode: 'override', profile: { id: 'chrome-windows' } });
|
|
expect(resolveUserAgent('https://other.example.test/', [assignment], [], 'Browser/Default'))
|
|
.toEqual({ hostname: 'other.example.test', mode: 'default', userAgent: 'Browser/Default' });
|
|
});
|
|
|
|
it('supports custom profiles and rejects unsafe header values', () => {
|
|
const custom: UserAgentProfile = {
|
|
id: 'custom-1', name: 'Custom', userAgent: 'Yakit-Test/1.0', category: 'custom', builtin: false,
|
|
};
|
|
expect(buildUserAgentDnrRules([{ ...assignment, profileId: custom.id }], [custom])[0].action)
|
|
.toMatchObject({ requestHeaders: [{ value: 'Yakit-Test/1.0' }] });
|
|
expect(validateUserAgent(' Safe-UA/1.0 ')).toBe('Safe-UA/1.0');
|
|
expect(() => validateUserAgent('Injected\r\nX-Test: yes')).toThrow('换行');
|
|
});
|
|
|
|
it('only accepts HTTP(S) targets', () => {
|
|
expect(userAgentHostname('http://127.0.0.1:8080/path')).toBe('127.0.0.1');
|
|
expect(() => userAgentHostname('chrome://extensions')).toThrow('HTTP');
|
|
});
|
|
});
|