-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathtest_constants.py
117 lines (98 loc) · 3.67 KB
/
test_constants.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
"""Test the pypdf.constants module."""
import re
from typing import Callable
import pytest
from pypdf.constants import PDF_KEYS, GraphicsStateParameters, UserAccessPermissions
def test_slash_prefix():
"""
Naming conventions of PDF_KEYS (constant names) are followed.
This test function validates if PDF key names follow the required pattern:
- Starts with a slash "/"
- Followed by an uppercase letter
- Contains alphanumeric characters (letters and digits)
- The attribute name should be a case-insensitive match, with underscores removed
"""
pattern = re.compile(r"^\/[A-Z]+[a-zA-Z0-9]*$")
for cls in PDF_KEYS:
for attr in dir(cls):
# Skip magic methods
if attr.startswith("__") and attr.endswith("__"):
continue
# Skip methods
constant_value = getattr(cls, attr)
if isinstance(constant_value, Callable):
continue
assert constant_value.startswith("/")
assert attr.replace("_", "").casefold() == constant_value[1:].casefold()
# There are a few exceptions that may be lowercase
if cls == GraphicsStateParameters and attr in ["ca", "op"]:
continue
assert pattern.match(constant_value)
def test_user_access_permissions__dict_handling():
# Value is mix of configurable and reserved bits.
# Reserved bits should not be part of the dictionary.
as_dict = UserAccessPermissions(512 + 64 + 8).to_dict()
assert as_dict == {
"add_or_modify": False,
"assemble_doc": False,
"extract": False,
"extract_text_and_graphics": True,
"fill_form_fields": False,
"modify": True,
"print": False,
"print_to_representation": False,
}
# Convert the dictionary back to an integer.
# This should add the reserved bits automatically.
permissions = UserAccessPermissions.from_dict(as_dict)
assert permissions == 4294963912
# Roundtrip for valid dictionary.
data = {
"add_or_modify": True,
"assemble_doc": False,
"extract": False,
"extract_text_and_graphics": True,
"fill_form_fields": False,
"modify": True,
"print": False,
"print_to_representation": True,
}
assert UserAccessPermissions.from_dict(data).to_dict() == data
# Empty inputs.
assert UserAccessPermissions.from_dict({}) == 4294963392 # Reserved bits.
assert UserAccessPermissions(0).to_dict() == {
"add_or_modify": False,
"assemble_doc": False,
"extract": False,
"extract_text_and_graphics": False,
"fill_form_fields": False,
"modify": False,
"print": False,
"print_to_representation": False,
}
# Unknown dictionary keys.
data = {
"add_or_modify": True,
"key1": False,
"key2": True,
}
unknown = {
"key1": False,
"key2": True,
}
with pytest.raises(
ValueError,
match=f"Unknown dictionary keys: {unknown!r}"
):
UserAccessPermissions.from_dict(data)
def test_user_access_permissions__all():
all_permissions = UserAccessPermissions.all()
all_int = int(all_permissions)
all_string = bin(all_permissions)
assert all_string.startswith("0b")
assert len(all_string[2:]) == 32 # 32-bit integer
assert all_int & UserAccessPermissions.R1 == 0
assert all_int & UserAccessPermissions.R2 == 0
assert all_int & UserAccessPermissions.PRINT == UserAccessPermissions.PRINT
assert all_int & UserAccessPermissions.R7 == UserAccessPermissions.R7
assert all_int & UserAccessPermissions.R31 == UserAccessPermissions.R31