"""Unit tests for the response transport codec (compression + msgpack).""" import base64 import json import pytest from browser_cli import transport def _sample(n=200): return { "id": "abc", "success": True, "data": {"items": [{"url": f"https://example.com/{i}", "title": f"Tab {i}"} for i in range(n)]}, } # ── backward compatibility ────────────────────────────────────────────────────── def test_no_accept_encoding_returns_bare_json(): obj = _sample() enc = transport.encode_response(obj, accept=None) assert enc == json.dumps(obj).encode("utf-8") # byte-identical to old wire format assert enc[:1] in (b"{", b"[") def test_empty_accept_returns_bare_json(): obj = _sample() assert transport.encode_response(obj, accept={}) == json.dumps(obj).encode("utf-8") def test_decode_plain_json_without_tag(): obj = _sample() assert transport.decode_response(json.dumps(obj).encode("utf-8")) == obj def test_decode_none_and_empty(): assert transport.decode_response(None) is None with pytest.raises(ValueError): transport.decode_response(b"") # ── compression roundtrips ─────────────────────────────────────────────────────── @pytest.mark.parametrize("comp", ["zlib", "gzip", "zstd"]) def test_compression_roundtrip(comp): if comp == "zstd" and not transport.zstd_available(): pytest.skip("zstandard not installed") obj = _sample() enc = transport.encode_response(obj, accept={"ser": ["json"], "comp": [comp]}) assert enc[:1] not in (b"{", b"[") # tagged, not plain assert len(enc) < len(json.dumps(obj)) # actually smaller assert transport.decode_response(enc) == obj def test_small_payload_not_compressed(): obj = {"id": "x", "success": True, "data": "ok"} enc = transport.encode_response(obj, accept={"ser": ["json"], "comp": ["zlib"]}, threshold=512) assert enc == json.dumps(obj).encode("utf-8") # below threshold → bare json def test_unknown_compression_in_accept_falls_back_to_plain(): obj = _sample() enc = transport.encode_response(obj, accept={"ser": ["json"], "comp": ["brotli"]}) assert enc == json.dumps(obj).encode("utf-8") # ── msgpack ────────────────────────────────────────────────────────────────────── def test_msgpack_roundtrip(): if not transport.msgpack_available(): pytest.skip("msgpack not installed") obj = _sample() enc = transport.encode_response(obj, accept={"ser": ["msgpack"], "comp": []}) assert enc[0] >> 4 == transport.SER_MSGPACK assert transport.decode_response(enc) == obj def test_msgpack_with_compression_roundtrip(): if not (transport.msgpack_available() and transport.zstd_available()): pytest.skip("msgpack/zstd not installed") obj = _sample() enc = transport.encode_response(obj, accept={"ser": ["msgpack"], "comp": ["zstd"]}) tag = enc[0] assert tag >> 4 == transport.SER_MSGPACK assert tag & 0x0F == transport.COMP_ZSTD assert transport.decode_response(enc) == obj # ── raw screenshot hoisting ─────────────────────────────────────────────────────── def _screenshot_obj(): png = bytes(range(256)) * 40 url = "data:image/png;base64," + base64.b64encode(png).decode("ascii") return {"id": "x", "success": True, "data": {"dataUrl": url}}, url def test_screenshot_roundtrip_restores_data_url_exactly(): if not transport.msgpack_available(): pytest.skip("msgpack not installed") obj, url = _screenshot_obj() enc = transport.encode_response(obj, accept={"ser": ["msgpack"], "comp": []}, command="tabs.screenshot") dec = transport.decode_response(enc) assert dec == obj assert dec["data"]["dataUrl"] == url def test_screenshot_not_hoisted_for_other_commands(): if not transport.msgpack_available(): pytest.skip("msgpack not installed") import msgpack obj, _ = _screenshot_obj() enc = transport.encode_response(obj, accept={"ser": ["msgpack"], "comp": []}, command="extract.text") body = msgpack.unpackb(enc[1:], raw=False) assert isinstance(body["data"]["dataUrl"], str) # left as base64 string def test_screenshot_json_path_leaves_base64(): obj, url = _screenshot_obj() enc = transport.encode_response(obj, accept={"ser": ["json"], "comp": ["gzip"]}, command="tabs.screenshot") assert transport.decode_response(enc)["data"]["dataUrl"] == url # ── negotiation preference ──────────────────────────────────────────────────────── def test_server_prefers_strongest_mutual_codec(): if not transport.zstd_available(): pytest.skip("zstandard not installed") obj = _sample() # client accepts gzip and zstd; server should pick zstd (its top preference) enc = transport.encode_response(obj, accept={"ser": ["json"], "comp": ["gzip", "zstd"]}) assert enc[0] & 0x0F == transport.COMP_ZSTD