disnake

Форк
0
/
test_permissions.py 
339 строк · 10.7 Кб
1
# SPDX-License-Identifier: MIT
2

3
from typing import Dict, Literal, Optional
4

5
import pytest
6

7
from disnake.permissions import PermissionOverwrite, Permissions
8

9

10
class TestPermissions:
11
    def test_init_permissions_keyword_arguments(self) -> None:
12
        perms = Permissions(manage_messages=True)
13

14
        assert perms.manage_messages is True
15

16
        # check we only have the manage message permission
17
        assert perms.value == Permissions.manage_messages.flag
18

19
    def test_init_permissions_keyword_arguments_with_aliases(self) -> None:
20
        assert Permissions(read_messages=True, view_channel=False).value == 0
21
        assert Permissions(view_channel=True, read_messages=False).value == 0
22

23
        assert Permissions(read_messages=False, view_channel=True).value == 1024
24
        assert Permissions(view_channel=False, read_messages=True).value == 1024
25

26
    def test_init_invalid_value(self) -> None:
27
        with pytest.raises(TypeError, match="Expected int parameter, received str instead."):
28
            Permissions("h")  # type: ignore
29

30
    def test_init_invalid_perms(self) -> None:
31
        with pytest.raises(TypeError, match="'h' is not a valid permission name."):
32
            Permissions(h=True)  # type: ignore
33

34
    @pytest.mark.parametrize(
35
        ("perms_int", "other_int", "expected"),
36
        [
37
            (0b11, 0b10, False),
38
            (0b10, 0b10, True),
39
            (0b01, 0b11, True),
40
        ],
41
    )
42
    def test_is_subset(self, perms_int: int, other_int: int, expected: bool) -> None:
43
        perms = Permissions(perms_int)
44
        other = Permissions(other_int)
45
        assert perms.is_subset(other) is expected
46

47
    def test_is_subset_only_permissions(self) -> None:
48
        perms = Permissions()
49
        with pytest.raises(TypeError, match="cannot compare Permissions with int"):
50
            perms.is_subset(5)  # type: ignore
51

52
    @pytest.mark.parametrize(
53
        ("perms_int", "other_int", "expected"),
54
        [
55
            (0b11, 0b10, True),
56
            (0b10, 0b10, True),
57
            (0b01, 0b11, False),
58
        ],
59
    )
60
    def test_is_superset(self, perms_int: int, other_int: int, expected: bool) -> None:
61
        perms = Permissions(perms_int)
62
        other = Permissions(other_int)
63
        assert perms.is_superset(other) is expected
64

65
    def test_is_superset_only_permissions(self) -> None:
66
        perms = Permissions()
67
        with pytest.raises(TypeError, match="cannot compare Permissions with int"):
68
            perms.is_superset(5)  # type: ignore
69

70
    @pytest.mark.parametrize(
71
        ("perms_int", "other_int", "expected"),
72
        [
73
            (0b11, 0b10, False),
74
            (0b10, 0b10, False),
75
            (0b01, 0b11, True),
76
        ],
77
    )
78
    def test_is_strict_subset(self, perms_int: int, other_int: int, expected: bool) -> None:
79
        perms = Permissions(perms_int)
80
        other = Permissions(other_int)
81
        assert perms.is_strict_subset(other) is expected
82

83
    @pytest.mark.parametrize(
84
        ("perms_int", "other_int", "expected"),
85
        [
86
            (0b11, 0b10, True),
87
            (0b10, 0b10, False),
88
            (0b01, 0b11, False),
89
        ],
90
    )
91
    def test_is_strict_superset(self, perms_int: int, other_int: int, expected: bool) -> None:
92
        perms = Permissions(perms_int)
93
        other = Permissions(other_int)
94

95
        assert perms.is_strict_superset(other) is expected
96

97
    @pytest.mark.parametrize(
98
        ("perms_dict", "update", "expected"),
99
        [
100
            (
101
                {"view_channel": True},
102
                {"move_members": True},
103
                {"view_channel": True, "move_members": True},
104
            ),
105
        ],
106
    )
107
    def test_update(
108
        self,
109
        perms_dict: Dict[str, bool],
110
        update: Dict[str, bool],
111
        expected: Dict[str, Literal[True]],
112
    ) -> None:
113
        perms = Permissions(**perms_dict)
114
        perms.update(**update)
115

116
        expected_perms = Permissions(**expected)
117

118
        assert perms.value == expected_perms.value
119

120
    @pytest.mark.parametrize(
121
        ("update", "expected"),
122
        [
123
            ({"read_messages": True, "view_channel": False}, 8),
124
            ({"view_channel": True, "read_messages": False}, 8),
125
            ({"read_messages": False, "view_channel": True}, 8 + 1024),
126
            ({"view_channel": False, "read_messages": True}, 8 + 1024),
127
        ],
128
    )
129
    def test_update_aliases(self, update: Dict[str, bool], expected: int) -> None:
130
        perms = Permissions(administrator=True)
131
        perms.update(**update)
132
        assert perms.value == expected
133

134
    @pytest.mark.parametrize(
135
        ("parameters", "expected"),
136
        [
137
            ({"view_channel": True, "move_members": True}, None),
138
            (
139
                # test aliases
140
                {"read_messages": True, "create_forum_threads": True},
141
                {"view_channel": True, "send_messages": True},
142
            ),
143
        ],
144
    )
145
    def test_iter(self, parameters: Dict[str, bool], expected: Optional[Dict[str, bool]]) -> None:
146
        perms = Permissions(**parameters)
147
        if expected is None:
148
            expected = parameters
149
        for key, value in iter(perms):
150
            assert value == expected.pop(key, False)
151
        assert not len(expected)
152

153
    def test_update_ignores(self) -> None:
154
        perms = Permissions()
155
        perms.update(h=True)  # type: ignore
156

157
    @pytest.mark.parametrize(
158
        ("initial", "allow", "deny", "expected"),
159
        [
160
            (0b1010, 0b0101, 0b1111, 0b0101),
161
            (0b0011, 0b0100, 0b0001, 0b0110),
162
            (0x0400, 0x0401, 0x5001, 0x0401),
163
        ],
164
    )
165
    def test_handle_overwrite(self, initial: int, allow: int, deny: int, expected: int) -> None:
166
        perms = Permissions(initial)
167
        assert perms.value == initial
168
        perms.handle_overwrite(allow, deny)
169
        assert perms.value == expected
170

171
    def test_none_is_none(self) -> None:
172
        perms = Permissions.none()
173
        assert perms.value == 0
174

175
    @pytest.mark.parametrize(
176
        "method_name",
177
        [
178
            "all",
179
            "none",
180
            "all_channel",
181
            "general",
182
            "membership",
183
            "text",
184
            "voice",
185
            "stage",
186
            "stage_moderator",
187
            "events",
188
            "advanced",
189
            "private_channel",
190
        ],
191
    )
192
    def test_classmethods(self, method_name: str) -> None:
193
        method = getattr(Permissions, method_name)
194

195
        perms: Permissions = method()
196
        assert isinstance(perms, Permissions)
197

198
        # check that caching does not return the same permissions instance
199
        perms_two: Permissions = method()
200
        assert perms is not perms_two
201
        assert perms.value == perms_two.value
202

203

204
class TestPermissionOverwrite:
205
    def test_init(self) -> None:
206
        perms = PermissionOverwrite(manage_messages=True)
207

208
        assert perms.manage_messages is True
209

210
    def test_init_invalid_perms(self) -> None:
211
        with pytest.raises(ValueError, match="'h' is not a valid permission name."):
212
            PermissionOverwrite(h=True)  # type: ignore
213

214
    def test_equality(self) -> None:
215
        one = PermissionOverwrite()
216
        two = PermissionOverwrite()
217

218
        assert one is not two
219
        assert one == two
220

221
        two.ban_members = False
222
        assert one != two
223

224
    def test_set(self) -> None:
225
        po = PermissionOverwrite()
226
        po.attach_files = False
227
        assert po.attach_files is False
228

229
        po.attach_files = True
230
        assert po.attach_files is True
231

232
        po.attach_files = None
233
        assert po.attach_files is None
234

235
    def test_set_invalid_type(self) -> None:
236
        po = PermissionOverwrite()
237
        with pytest.raises(TypeError, match="Expected bool or NoneType, received str"):
238
            po.connect = "h"  # type: ignore
239

240
        with pytest.raises(
241
            AttributeError, match="'PermissionOverwrite' object has no attribute 'oh'"
242
        ):
243
            po.oh = False  # type: ignore
244

245
    @pytest.mark.parametrize(
246
        ("allow", "deny"),
247
        [
248
            ({"view_channel": True}, {"ban_members": True}),
249
            ({"view_channel": True}, {"view_channel": True}),
250
            ({"administrator": True}, {"manage_channels": False}),
251
        ],
252
    )
253
    def test_from_pair(
254
        self,
255
        allow: Dict[str, bool],
256
        deny: Dict[str, bool],
257
    ) -> None:
258
        perm_allow = Permissions(**allow)
259
        perm_deny = Permissions(**deny)
260

261
        po = PermissionOverwrite.from_pair(perm_allow, perm_deny)
262

263
        # iterate over the allowed perms and assert that the overwrite is what the allowed perms are
264
        for perm, allowed in perm_allow:
265
            # get the attr from the denied perms as denied perms override the allow list in from_pair
266
            if allowed and not getattr(perm_deny, perm):
267
                assert getattr(po, perm) is True
268
            else:
269
                assert getattr(po, perm) is not True
270

271
        for perm, denied in deny.items():
272
            if denied:
273
                assert getattr(po, perm) is False
274
            else:
275
                assert getattr(po, perm) is not False
276

277
    @pytest.mark.parametrize(
278
        ("allow", "deny"),
279
        [
280
            # these intentionally do not interfere with each other
281
            (0b1, 0b10),
282
            (0x313, 0x424),
283
            (0x69420, 0x2301),
284
        ],
285
    )
286
    def test_pair(self, allow: int, deny: int) -> None:
287
        og_perms_allow = Permissions(allow)
288
        og_perms_deny = Permissions(deny)
289

290
        po = PermissionOverwrite.from_pair(og_perms_allow, og_perms_deny)
291

292
        perms_allow, perms_deny = po.pair()
293

294
        assert perms_allow.value == og_perms_allow.value
295
        assert perms_deny.value == og_perms_deny.value
296

297
    def test_is_empty(self) -> None:
298
        po = PermissionOverwrite()
299
        assert po.is_empty()
300

301
        po.add_reactions = True
302
        assert not po.is_empty()
303

304
    def test_update(self) -> None:
305
        po = PermissionOverwrite()
306
        assert po.manage_emojis is None
307

308
        po.update(manage_emojis=True)
309
        assert po.manage_emojis is True
310

311
        assert po.manage_permissions is None
312
        po.update(manage_permissions=False)
313
        assert po.manage_permissions is False
314

315
        po.update(manage_permissions=None, manage_emojis=None)
316
        assert po.manage_permissions is None
317
        assert po.manage_emojis is None
318

319
        # invalid names are silently ignored
320
        po.update(h=True)  # type: ignore
321
        assert not hasattr(po, "h")
322

323
    @pytest.mark.parametrize(
324
        ("expected"),
325
        [
326
            ({"view_channel": True}),
327
            ({"ban_members": None}),
328
            ({"view_channel": True, "administrator": False, "ban_members": None}),
329
            ({"kick_members": False}),
330
        ],
331
    )
332
    def test_iter(
333
        self,
334
        expected: Dict[str, bool],
335
    ) -> None:
336
        po = PermissionOverwrite(**expected)
337

338
        for perm, value in po:
339
            assert expected.get(perm, None) is value
340

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.