1 import { WEBSITE_RULES_SUPPORTED_VERSION } from '@proton/pass/constants';
2 import type { WebsiteRules } from '@proton/pass/types';
4 import { getRulesForURL, parseRules, validateRules } from './website-rules';
6 describe('Website rules', () => {
7 const rules: WebsiteRules = {
8 version: WEBSITE_RULES_SUPPORTED_VERSION,
10 'example.com': ['rule > host > 1', 'rule > host > 2'],
11 'example.com/path': ['rule > path > 1'],
12 'proton.me/path': ['rule > path > 2'],
16 describe('`validateRules`', () => {
17 test('returns `true` if valid object for current supported version', () => {
18 expect(validateRules(rules)).toBe(true);
21 test('returns `false` if valid object but unsupported version', () => {
22 expect(validateRules({ ...rules, version: '2' })).toBe(false);
25 test('returns `false` on invalid data', () => {
26 expect(validateRules({})).toBe(false);
27 expect(validateRules(null)).toBe(false);
28 expect(validateRules(undefined)).toBe(false);
29 expect(validateRules({ ...rules, rules: [] })).toBe(false);
30 expect(validateRules({ ...rules, rules: { 'example.com': 'rule' } })).toBe(false);
34 describe('`parseRules`', () => {
35 test('returns parsed rules', () => {
36 expect(parseRules(JSON.stringify(rules))).toEqual(rules);
39 test('returns `null` if parsing fails', () => {
40 expect(parseRules(null)).toEqual(null);
41 expect(parseRules('{}')).toEqual(null);
42 expect(parseRules('not-json')).toEqual(null);
43 expect(parseRules(JSON.stringify({ ...rules, version: '2' }))).toEqual(null);
47 describe('`getRulesForURL`', () => {
48 test('returns hostname rules for a clean URL without path', () => {
49 const result = getRulesForURL(rules, new URL('https://example.com'));
50 expect(result).toEqual(['rule > host > 1', 'rule > host > 2']);
53 test('returns hostname rules for an unclean URL without path', () => {
54 const result = getRulesForURL(rules, new URL('https://example.com/#hash?search=test'));
55 expect(result).toEqual(['rule > host > 1', 'rule > host > 2']);
58 test('returns hostname & pathname rules for a clean URL with pathname', () => {
59 const result = getRulesForURL(rules, new URL('https://example.com/path'));
60 expect(result).toEqual(['rule > host > 1', 'rule > host > 2', 'rule > path > 1']);
63 test('returns hostname & pathname rules for an unclean URL with pathname', () => {
64 const result = getRulesForURL(rules, new URL('https://example.com/path#hash?search=test/'));
65 expect(result).toEqual(['rule > host > 1', 'rule > host > 2', 'rule > path > 1']);
68 test('returns empty array when no rules exist for the URL', () => {
69 const result = getRulesForURL(rules, new URL('https://example.org'));
70 expect(result).toEqual([]);
73 test('returns empty array if the URL has no pathname and rules exist only for the same URL with pathname', async () => {
74 const result = getRulesForURL(rules, new URL('https://proton.me'));
75 expect(result).toEqual([]);