Files
yaklang-chrome-extension/src/features/identity/user-agent.test.ts
T

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');
});
});