-
Notifications
You must be signed in to change notification settings - Fork 166
Expand file tree
/
Copy pathtest_encoding.py
More file actions
123 lines (97 loc) · 3.51 KB
/
Copy pathtest_encoding.py
File metadata and controls
123 lines (97 loc) · 3.51 KB
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
118
119
120
121
122
123
"""Tests for meraki.encoding module (HTTP-04, QUAL-03)."""
import inspect
from hypothesis import given, strategies as st
from urllib.parse import parse_qs
from meraki.encoding import encode_meraki_params
class TestEncodeMerakiParams:
"""Unit tests replicating behavioral spec from test_rest_session.py."""
def test_string_passthrough(self):
assert encode_meraki_params("already_encoded") == "already_encoded"
def test_bytes_passthrough(self):
assert encode_meraki_params(b"raw") == b"raw"
def test_file_like_passthrough(self):
class FakeFile:
def read(self):
pass
f = FakeFile()
assert encode_meraki_params(f) is f
def test_non_iterable_passthrough(self):
assert encode_meraki_params(42) == 42
def test_simple_dict(self):
result = encode_meraki_params({"key": "value"})
assert "key=value" in result
def test_list_values(self):
result = encode_meraki_params({"tag": ["a", "b"]})
assert "tag=a" in result
assert "tag=b" in result
def test_array_of_objects(self):
result = encode_meraki_params({"param[]": [{"key1": "val1"}, {"key2": "val2"}]})
assert "param%5B%5Dkey1=val1" in result
assert "param%5B%5Dkey2=val2" in result
def test_list_of_tuples(self):
result = encode_meraki_params([("k", "v")])
assert "k=v" in result
class TestNoRequestsDependency:
"""Verify HTTP-04: no requests import in encoding module."""
def test_no_requests_import(self):
import meraki.encoding
source = inspect.getsource(meraki.encoding)
assert "import requests" not in source
assert "from requests" not in source
# --- Property-based tests (QUAL-03, per D-04: roundtrip fidelity) ---
# Strategy: printable text keys (no surrogates, no empty)
_key_strategy = st.text(
alphabet=st.characters(whitelist_categories=("L", "N", "P"), blacklist_characters="=&#"),
min_size=1,
max_size=20,
)
_value_strategy = st.text(
alphabet=st.characters(whitelist_categories=("L", "N", "P"), blacklist_characters="=&#"),
min_size=1,
max_size=50,
)
@given(
st.dictionaries(
keys=_key_strategy,
values=st.lists(_value_strategy, min_size=1, max_size=5),
)
)
def test_roundtrip_simple(data):
"""(D-04) Encoded output parsed back with parse_qs reconstructs keys and values."""
encoded = encode_meraki_params(data)
if not data:
assert encoded == ""
return
decoded = parse_qs(encoded)
assert set(decoded.keys()) == set(data.keys())
for k in data:
assert decoded[k] == data[k]
@given(
st.dictionaries(
keys=_key_strategy,
values=st.lists(
st.dictionaries(
keys=_key_strategy,
values=_value_strategy,
min_size=1,
max_size=3,
),
min_size=1,
max_size=3,
),
)
)
def test_roundtrip_array_of_objects(data):
"""(D-04, D-05) Array-of-objects encoding roundtrips: param+inner_key maps to value."""
encoded = encode_meraki_params(data)
if not data:
assert encoded == ""
return
decoded = parse_qs(encoded)
# Verify all expected keys exist
for param, obj_list in data.items():
for obj in obj_list:
for inner_key, inner_val in obj.items():
composite_key = param + inner_key
assert composite_key in decoded
assert inner_val in decoded[composite_key]