File: test_constants.py

package info (click to toggle)
pypdf 6.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 18,184 kB
  • sloc: python: 48,595; makefile: 35
file content (117 lines) | stat: -rw-r--r-- 3,757 bytes parent folder | download | duplicates (2)
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