Skip to content

Commit b35cced

Browse files
test: add tests for browser preferences validation
1 parent 9b3cc1d commit b35cced

File tree

2 files changed

+167
-5
lines changed

2 files changed

+167
-5
lines changed

pydoll/browser/preference_types.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
from typing import NotRequired, TypedDict
22

33

4-
class DownloadPreferences(TypedDict, total=False):
4+
class DownloadPreferences(TypedDict):
55
default_directory: str
6-
prompt_for_download: bool
6+
prompt_for_download: NotRequired[bool]
7+
directory_upgrade: NotRequired[bool]
78

89

9-
class ProfilePreferences(TypedDict, total=False):
10+
class ContentSettingValues(TypedDict, total=False):
11+
popups: int
12+
notifications: int
13+
automatic_downloads: int
14+
15+
16+
class ProfilePreferences(TypedDict):
1017
password_manager_enabled: bool
11-
# maps content setting name -> int (e.g. popups: 0 or 1)
12-
default_content_setting_values: NotRequired[dict[str, int]]
18+
default_content_setting_values: ContentSettingValues
1319

1420

1521
class BrowserPreferences(TypedDict, total=False):
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import pytest
2+
from typing import Any, cast
3+
4+
from pydoll.browser.options import ChromiumOptions
5+
from pydoll.browser.preference_types import BrowserPreferences
6+
from pydoll.exceptions import InvalidPreferencePath, InvalidPreferenceValue, WrongPrefsDict
7+
8+
9+
def test_validate_pref_path_valid():
10+
"""Test that valid preference paths are accepted."""
11+
options = ChromiumOptions()
12+
# Should not raise
13+
options._validate_pref_path(['download', 'default_directory'])
14+
options._validate_pref_path(['profile', 'password_manager_enabled'])
15+
options._validate_pref_path(['plugins', 'always_open_pdf_externally'])
16+
17+
18+
def test_validate_pref_path_invalid():
19+
"""Test that invalid preference paths raise InvalidPreferencePath."""
20+
options = ChromiumOptions()
21+
with pytest.raises(InvalidPreferencePath):
22+
options._validate_pref_path(['invalid', 'path'])
23+
with pytest.raises(InvalidPreferencePath):
24+
options._validate_pref_path(['download', 'invalid_key'])
25+
26+
27+
def test_validate_pref_value_valid():
28+
"""Test that valid preference values are accepted."""
29+
options = ChromiumOptions()
30+
# Should not raise
31+
options._validate_pref_value(['download', 'default_directory'], '/path/to/dir')
32+
options._validate_pref_value(['profile', 'password_manager_enabled'], True)
33+
options._validate_pref_value(['profile', 'default_content_setting_values', 'popups'], 1)
34+
35+
36+
def test_validate_pref_value_invalid():
37+
"""Test that invalid preference values raise InvalidPreferenceValue."""
38+
options = ChromiumOptions()
39+
with pytest.raises(InvalidPreferenceValue):
40+
options._validate_pref_value(['download', 'default_directory'], True) # should be str
41+
with pytest.raises(InvalidPreferenceValue):
42+
options._validate_pref_value(['profile', 'password_manager_enabled'], 'true') # should be bool
43+
44+
45+
def test_browser_preferences_setter_valid():
46+
"""Test setting valid browser preferences."""
47+
options = ChromiumOptions()
48+
prefs: BrowserPreferences = {
49+
'download': {
50+
'default_directory': '/downloads',
51+
'prompt_for_download': True
52+
},
53+
'profile': {
54+
'password_manager_enabled': False,
55+
'default_content_setting_values': {
56+
'popups': 0,
57+
'notifications': 2
58+
}
59+
}
60+
}
61+
options.browser_preferences = prefs
62+
assert options.browser_preferences == prefs
63+
64+
65+
def test_browser_preferences_setter_invalid_type():
66+
"""Test setting browser preferences with invalid type."""
67+
options = ChromiumOptions()
68+
with pytest.raises(ValueError):
69+
# type: ignore[arg-type]
70+
options.browser_preferences = ['not', 'a', 'dict']
71+
72+
73+
def test_browser_preferences_setter_invalid_prefs():
74+
"""Test setting browser preferences with invalid prefs key."""
75+
options = ChromiumOptions()
76+
with pytest.raises(WrongPrefsDict):
77+
invalid_prefs = cast(BrowserPreferences, {'prefs': {'some': 'value'}})
78+
options.browser_preferences = invalid_prefs
79+
80+
81+
def test_browser_preferences_merge():
82+
"""Test that browser preferences are properly merged."""
83+
options = ChromiumOptions()
84+
initial_prefs: BrowserPreferences = {
85+
'download': {
86+
'default_directory': '/downloads',
87+
'prompt_for_download': True
88+
},
89+
'profile': {
90+
'password_manager_enabled': True,
91+
'default_content_setting_values': {
92+
'popups': 0
93+
}
94+
}
95+
}
96+
additional_prefs: BrowserPreferences = {
97+
'profile': {
98+
'password_manager_enabled': False,
99+
'default_content_setting_values': {
100+
'notifications': 2
101+
}
102+
}
103+
}
104+
105+
options.browser_preferences = initial_prefs
106+
options.browser_preferences = additional_prefs
107+
108+
expected: BrowserPreferences = {
109+
'download': {
110+
'default_directory': '/downloads',
111+
'prompt_for_download': True
112+
},
113+
'profile': {
114+
'password_manager_enabled': False,
115+
'default_content_setting_values': {
116+
'notifications': 2
117+
}
118+
}
119+
}
120+
assert options.browser_preferences == expected
121+
122+
123+
def test_get_pref_path_existing():
124+
"""Test getting existing preference paths."""
125+
options = ChromiumOptions()
126+
prefs: BrowserPreferences = {
127+
'download': {
128+
'default_directory': '/downloads',
129+
},
130+
'profile': {
131+
'password_manager_enabled': True,
132+
'default_content_setting_values': {}
133+
}
134+
}
135+
options.browser_preferences = prefs
136+
assert options._get_pref_path(['download', 'default_directory']) == '/downloads'
137+
138+
139+
def test_get_pref_path_nonexistent():
140+
"""Test getting nonexistent preference paths returns None."""
141+
options = ChromiumOptions()
142+
with pytest.raises(InvalidPreferencePath):
143+
options._get_pref_path(['download', 'nonexistent'])
144+
145+
146+
def test_set_pref_path_creates_structure():
147+
"""Test that setting a preference path creates the necessary structure."""
148+
options = ChromiumOptions()
149+
options.browser_preferences = cast(BrowserPreferences, {
150+
'profile': {
151+
'password_manager_enabled': True,
152+
'default_content_setting_values': {}
153+
}
154+
})
155+
options._set_pref_path(['profile', 'default_content_setting_values', 'popups'], 0)
156+
assert cast(Any, options.browser_preferences)['profile']['default_content_setting_values']['popups'] == 0

0 commit comments

Comments
 (0)