Update selected item color in Pass menu
[ProtonMail-WebClient.git] / packages / pass / lib / search / match-url.spec.ts
blob6b4486e5a267fb81682b0d37cb5a48cc55700fda
1 import type { Item } from '@proton/pass/types';
3 import { ItemUrlMatch, getItemPriorityForUrl } from './match-url';
5 const createMockItem = (urls: string[]) => ({ type: 'login', content: { urls } }) as unknown as Item<'login'>;
6 const filter = { protocol: null, port: null, isPrivate: false };
8 describe('match url', () => {
9     describe('`getItemPriorityForUrl`', () => {
10         test('should return `NO_MATCH` if domains do not match', () => {
11             const item = createMockItem(['https://proton.ch']);
12             const result = getItemPriorityForUrl(item)('pm.me', filter);
13             expect(result).toBe(ItemUrlMatch.NO_MATCH);
14         });
16         test('should return `NO_MATCH` if item has no urls', () => {
17             const item = createMockItem([]);
18             const result = getItemPriorityForUrl(item)('pm.me', filter);
19             expect(result).toBe(ItemUrlMatch.NO_MATCH);
20         });
22         test('should return `NO_MATCH` if empty domain & item has no urls', () => {
23             const item = createMockItem([]);
24             const result = getItemPriorityForUrl(item)('', filter);
25             expect(result).toBe(ItemUrlMatch.NO_MATCH);
26         });
28         test('should return `NO_MATCH` if item URL is a non-valid substring of domain', () => {
29             const item1 = createMockItem(['https://pproton.ch']);
30             const result1 = getItemPriorityForUrl(item1)('proton.ch', filter);
31             expect(result1).toBe(ItemUrlMatch.NO_MATCH);
33             const item2 = createMockItem(['https://p.pproton.ch']);
34             const result2 = getItemPriorityForUrl(item2)('proton.ch', filter);
35             expect(result2).toBe(ItemUrlMatch.NO_MATCH);
36         });
38         test('should return `NO_MATCH` if protocols differ', () => {
39             const item1 = createMockItem(['https://proton.ch']);
40             const result1 = getItemPriorityForUrl(item1)('proton.ch', { ...filter, protocol: 'http:' });
41             expect(result1).toBe(ItemUrlMatch.NO_MATCH);
43             const item2 = createMockItem(['ftp://proton.ch']);
44             const result2 = getItemPriorityForUrl(item2)('proton.ch', { ...filter, protocol: 'https:' });
45             expect(result2).toBe(ItemUrlMatch.NO_MATCH);
47             const item3 = createMockItem(['ftp://sub.proton.ch']);
48             const result3 = getItemPriorityForUrl(item3)('proton.ch', { ...filter, protocol: 'https:' });
49             expect(result3).toBe(ItemUrlMatch.NO_MATCH);
50         });
52         test('should return `NO_MATCH` if ports differ', () => {
53             const item1 = createMockItem(['https://proton.ch:3002']);
54             const result1 = getItemPriorityForUrl(item1)('proton.ch', { ...filter, port: '3001' });
55             expect(result1).toBe(ItemUrlMatch.NO_MATCH);
57             const item2 = createMockItem(['ftp://proton.ch:3002']);
58             const result2 = getItemPriorityForUrl(item2)('proton.ch', { ...filter, port: '3001' });
59             expect(result2).toBe(ItemUrlMatch.NO_MATCH);
61             const item3 = createMockItem(['ftp://sub.proton.ch:3002']);
62             const result3 = getItemPriorityForUrl(item3)('proton.ch', { ...filter, port: '3001' });
63             expect(result3).toBe(ItemUrlMatch.NO_MATCH);
64         });
66         test('should return `NO_MATCH` if deeper private subdomain', () => {
67             const item = createMockItem(['https://a.b.c.me']);
68             const result = getItemPriorityForUrl(item)('b.c.me', { ...filter, isPrivate: true });
69             expect(result).toBe(ItemUrlMatch.NO_MATCH);
70         });
72         test('should return `NO_MATCH` on invalid item URLs', () => {
73             const item1 = createMockItem(['https::/proton.ch']);
74             const item2 = createMockItem([',,,,/proton.ch', ' ']);
75             const item3 = createMockItem(['', 'https://proton.me']);
77             expect(getItemPriorityForUrl(item1)('proton.ch', filter)).toBe(ItemUrlMatch.NO_MATCH);
78             expect(getItemPriorityForUrl(item2)('proton.ch', filter)).toBe(ItemUrlMatch.NO_MATCH);
79             expect(getItemPriorityForUrl(item3)('proton.ch', filter)).toBe(ItemUrlMatch.NO_MATCH);
80         });
82         test('should return `NO_MATCH` for non exact matches in strict mode', () => {
83             const item1 = createMockItem(['https://example.com']);
84             const result1 = getItemPriorityForUrl(item1)('b.example.com', { ...filter, strict: true });
85             expect(result1).toBe(ItemUrlMatch.NO_MATCH);
87             const item2 = createMockItem(['https://a.b.example.com']);
88             const result2 = getItemPriorityForUrl(item2)('b.example.com', { ...filter, strict: true });
89             expect(result2).toBe(ItemUrlMatch.NO_MATCH);
91             const item3 = createMockItem(['https://a.example.com']);
92             const result3 = getItemPriorityForUrl(item3)('b.example.com', { ...filter, strict: true });
93             expect(result3).toBe(ItemUrlMatch.NO_MATCH);
95             const item4 = createMockItem(['https://sub.example.com']);
96             const result4 = getItemPriorityForUrl(item4)('b.example.com', { ...filter, strict: true });
97             expect(result4).toBe(ItemUrlMatch.NO_MATCH);
98         });
100         test('should return `SUB_MATCH` on subdomain match', () => {
101             const item1 = createMockItem(['https://subdomain.pm.me']);
102             const result1 = getItemPriorityForUrl(item1)('pm.me', filter);
103             expect(result1).toBe(ItemUrlMatch.SUB_MATCH);
105             const item2 = createMockItem(['http://nested.subdomain.pm.me']);
106             const result2 = getItemPriorityForUrl(item2)('subdomain.pm.me', filter);
107             expect(result2).toBe(ItemUrlMatch.SUB_MATCH);
108         });
110         test('should return `SUB_MATCH` on subdomain accounting for protocol', () => {
111             const item = createMockItem(['http://sub.proton.ch']);
112             const result = getItemPriorityForUrl(item)('proton.ch', { ...filter, protocol: 'http:' });
113             expect(result).toBe(ItemUrlMatch.SUB_MATCH);
114         });
116         test('should return `SUB_MATCH` on subdomain accounting for port', () => {
117             const item = createMockItem(['http://sub.proton.ch:3001']);
118             const result = getItemPriorityForUrl(item)('proton.ch', { ...filter, port: '3001' });
119             expect(result).toBe(ItemUrlMatch.SUB_MATCH);
120         });
122         test('should return `SUB_MATCH` on subdomain with port if no port filter', () => {
123             const item = createMockItem(['http://sub.proton.ch:3001']);
124             const result = getItemPriorityForUrl(item)('proton.ch', filter);
125             expect(result).toBe(ItemUrlMatch.SUB_MATCH);
126         });
128         test('should return `SUB_MATCH` on deeper non-private subdomain matches', () => {
129             const item1 = createMockItem(['https://a.b.c.me']);
130             const result1 = getItemPriorityForUrl(item1)('a.b.c.me', filter);
131             expect(result1).toBe(ItemUrlMatch.SUB_MATCH);
133             const item2 = createMockItem(['https://a.b.c.me']);
134             const result2 = getItemPriorityForUrl(item2)('b.c.me', filter);
135             expect(result2).toBe(ItemUrlMatch.SUB_MATCH);
136         });
138         test('should return `SUB_MATCH` on subdomain with query parameters', () => {
139             const item = createMockItem(['https://sub.example.com/path?query=param']);
140             const result = getItemPriorityForUrl(item)('example.com', filter);
141             expect(result).toBe(ItemUrlMatch.SUB_MATCH);
142         });
144         test('should return `SUB_MATCH` on exact subdomain in strict mode', () => {
145             const item = createMockItem(['https://example.com', 'https://a.example.com']);
146             const result = getItemPriorityForUrl(item)('a.example.com', { ...filter, strict: true });
147             expect(result).toBe(ItemUrlMatch.SUB_MATCH);
148         });
150         test('should return `TOP_MATCH` on top-level domain match', () => {
151             const item1 = createMockItem(['https://pm.me']);
152             const result1 = getItemPriorityForUrl(item1)('pm.me', filter);
153             expect(result1).toBe(ItemUrlMatch.TOP_MATCH);
155             const item2 = createMockItem(['nomatch', 'https://proton.ch']);
156             const result2 = getItemPriorityForUrl(item2)('proton.ch', filter);
157             expect(result2).toBe(ItemUrlMatch.TOP_MATCH);
158         });
160         test('should return `TOP_MATCH` on top-level domain accounting for protocol', () => {
161             const item = createMockItem(['ftp://proton.ch']);
162             const result = getItemPriorityForUrl(item)('proton.ch', { ...filter, protocol: 'ftp:' });
163             expect(result).toBe(ItemUrlMatch.TOP_MATCH);
164         });
166         test('should return `TOP_MATCH` on top-level domain accounting for port', () => {
167             const item = createMockItem(['http://proton.ch:3001']);
168             const result = getItemPriorityForUrl(item)('proton.ch', { ...filter, port: '3001' });
169             expect(result).toBe(ItemUrlMatch.TOP_MATCH);
170         });
172         test('should return `TOP_MATCH` on url with port if no port filter', () => {
173             const item = createMockItem(['http://proton.ch:3001']);
174             const result = getItemPriorityForUrl(item)('proton.ch', filter);
175             expect(result).toBe(ItemUrlMatch.TOP_MATCH);
176         });
178         test('should return `TOP_MATCH` when matching by IP address', () => {
179             const item1 = createMockItem(['http://192.168.1.1']);
180             const result1 = getItemPriorityForUrl(item1)('192.168.1.1', filter);
181             expect(result1).toBe(ItemUrlMatch.TOP_MATCH);
183             const item2 = createMockItem(['https://192.168.1.1/path']);
184             const result2 = getItemPriorityForUrl(item2)('192.168.1.1', filter);
185             expect(result2).toBe(ItemUrlMatch.TOP_MATCH);
186         });
188         test('should return `TOP_MATCH` on top-level domain with query parameters', () => {
189             const item = createMockItem(['https://example.com/path?query=param']);
190             const result = getItemPriorityForUrl(item)('example.com', filter);
191             expect(result).toBe(ItemUrlMatch.TOP_MATCH);
192         });
194         test('should return `TOP_MATCH` on exact domain in strict mode', () => {
195             const item1 = createMockItem(['https://example.com']);
196             const result1 = getItemPriorityForUrl(item1)('example.com', { ...filter, strict: true });
197             expect(result1).toBe(ItemUrlMatch.TOP_MATCH);
199             const item2 = createMockItem(['https://sub.example.com', 'https://example.com']);
200             const result2 = getItemPriorityForUrl(item2)('example.com', { ...filter, strict: true });
201             expect(result2).toBe(ItemUrlMatch.TOP_MATCH);
202         });
203     });