# retoor import pytest from stealthii import Stealthii, StealthResponse from stealthii.client import _ContextSlot def test_construction_is_lazy_and_cheap(): s = Stealthii() assert s._browser is None assert s._playwright is None assert s._contexts == {} def test_invalid_fingerprint_rejected(): with pytest.raises(ValueError): Stealthii(fingerprint='ja5') def test_defaults(): s = Stealthii() assert s.fingerprint == 'ja4' assert s.max_tabs == 4 assert s.max_retries == 3 assert s.recycle_context_after_count == 500 assert s.recycle_context_after_s == 1800.0 def test_build_body_json(): headers = {} kwargs = Stealthii._build_body(headers, data=None, json={'a': 1}, files=None) assert kwargs == {'data': '{"a": 1}'} assert headers['Content-Type'] == 'application/json' def test_build_body_form_dict(): kwargs = Stealthii._build_body({}, data={'x': '1'}, json=None, files=None) assert kwargs == {'form': {'x': '1'}} def test_build_body_raw_bytes(): kwargs = Stealthii._build_body({}, data=b'raw', json=None, files=None) assert kwargs == {'data': b'raw'} def test_build_body_none(): assert Stealthii._build_body({}, data=None, json=None, files=None) == {} def test_build_body_multipart_with_files_and_fields(): kwargs = Stealthii._build_body( {}, data={'field': 'value'}, json=None, files={'upload': ('name.txt', b'content')}, ) multipart = kwargs['multipart'] assert multipart['field'] == 'value' assert multipart['upload']['name'] == 'name.txt' assert multipart['upload']['buffer'] == b'content' @pytest.mark.asyncio async def test_stealth_response_shapes_like_aiohttp(): resp = StealthResponse(200, {'Content-Type': 'application/json'}, b'{"ok": true}', 'https://x/') assert resp.status == 200 assert await resp.text() == '{"ok": true}' assert await resp.json() == {'ok': True} assert await resp.read() == b'{"ok": true}' async with resp as r: assert r is resp def test_context_slot_starts_fresh(): slot = _ContextSlot(context=object()) assert slot.count == 0 assert slot.patched is False