From 047094759df55f5a7eb02212c946603d7aa9b8e3 Mon Sep 17 00:00:00 2001 From: Kristian Vastveit Date: Sun, 12 Apr 2026 15:01:43 +0200 Subject: [PATCH] test: add unit tests for signing, bypass, and hook --- tests/__init__.py | 0 tests/conftest.py | 36 +++++++++++++++ tests/test_bypass.py | 95 +++++++++++++++++++++++++++++++++++++++ tests/test_hook.py | 101 ++++++++++++++++++++++++++++++++++++++++++ tests/test_signing.py | 76 +++++++++++++++++++++++++++++++ 5 files changed, 308 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_bypass.py create mode 100644 tests/test_hook.py create mode 100644 tests/test_signing.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..4bfaa07 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,36 @@ +# pyright: reportMissingImports=false, reportUnknownMemberType=false, reportUntypedFunctionDecorator=false, reportUnknownParameterType=false, reportMissingParameterType=false, reportUnknownVariableType=false, reportUnknownArgumentType=false + +import pytest + + +@pytest.fixture +def simple_messages(): + return [{"role": "user", "content": "hello world"}] + + +@pytest.fixture +def complex_messages(): + return [ + { + "role": "user", + "content": [ + {"type": "image", "source": {"type": "base64", "data": "abc"}}, + {"type": "text", "text": "hello world"}, + ], + } + ] + + +@pytest.fixture +def basic_api_kwargs(simple_messages): + return { + "system": [ + { + "type": "text", + "text": "You are Claude Code, Anthropic's official CLI for Claude.\nStay helpful.", + }, + {"type": "text", "text": "Extra system guidance"}, + ], + "messages": [dict(message) for message in simple_messages], + "model": "claude-opus-4-6-20260101", + } diff --git a/tests/test_bypass.py b/tests/test_bypass.py new file mode 100644 index 0000000..ff5d936 --- /dev/null +++ b/tests/test_bypass.py @@ -0,0 +1,95 @@ +# pyright: reportPrivateUsage=false, reportUnknownParameterType=false, reportMissingParameterType=false, reportUnknownArgumentType=false, reportUnknownVariableType=false, reportUnknownMemberType=false, reportArgumentType=false + +import copy + +from anthropic_billing_bypass import ( + _SYSTEM_IDENTITY, + _fix_temperature_for_oauth_adaptive, + apply_claude_code_bypass, +) + + +def test_apply_claude_code_bypass_injects_billing_header_and_preserves_identity( + basic_api_kwargs, +): + apply_claude_code_bypass(basic_api_kwargs, "2.1.90") + + system = basic_api_kwargs["system"] + assert system[0]["text"].startswith("x-anthropic-billing-header: ") + assert system[1]["text"] == _SYSTEM_IDENTITY + + +def test_apply_claude_code_bypass_relocates_non_identity_system_text_to_first_user_message( + basic_api_kwargs, +): + apply_claude_code_bypass(basic_api_kwargs, "2.1.90") + + user_content = basic_api_kwargs["messages"][0]["content"] + assert isinstance(user_content, list) + text = user_content[0]["text"] + assert "\nStay helpful.\n" in text + assert "\nExtra system guidance\n" in text + assert text.endswith("hello world") + + +def test_apply_claude_code_bypass_is_idempotent(basic_api_kwargs): + apply_claude_code_bypass(basic_api_kwargs, "2.1.90") + once = copy.deepcopy(basic_api_kwargs) + + apply_claude_code_bypass(basic_api_kwargs, "2.1.90") + + assert len(basic_api_kwargs["system"]) == 2 + assert basic_api_kwargs["system"][0]["text"].startswith( + "x-anthropic-billing-header: " + ) + assert basic_api_kwargs["system"][1]["text"] == _SYSTEM_IDENTITY + assert basic_api_kwargs["messages"] == once["messages"] + + +def test_apply_claude_code_bypass_normalizes_string_system(simple_messages): + api_kwargs = { + "system": "plain system", + "messages": [dict(message) for message in simple_messages], + "model": "claude-opus-4-6-20260101", + } + + apply_claude_code_bypass(api_kwargs, "2.1.90") + + assert isinstance(api_kwargs["system"], list) + assert api_kwargs["system"][1]["text"] == _SYSTEM_IDENTITY + assert ( + "\nplain system\n" + in api_kwargs["messages"][0]["content"][0]["text"] + ) + + +def test_apply_claude_code_bypass_without_messages_is_noop(): + api_kwargs = {"system": "plain system", "model": "claude-opus-4-6-20260101"} + + apply_claude_code_bypass(api_kwargs, "2.1.90") + + assert api_kwargs == {"system": "plain system", "model": "claude-opus-4-6-20260101"} + + +def test_fix_temperature_for_oauth_adaptive_removes_non_default_temperature(): + api_kwargs = {"model": "claude-opus-4-6-20260101", "temperature": 0.2} + _fix_temperature_for_oauth_adaptive(api_kwargs, site="test") + assert "temperature" not in api_kwargs + + +def test_fix_temperature_for_oauth_adaptive_keeps_temperature_one(): + api_kwargs = {"model": "claude-opus-4-6-20260101", "temperature": 1} + _fix_temperature_for_oauth_adaptive(api_kwargs, site="test") + assert api_kwargs["temperature"] == 1 + + +def test_fix_temperature_for_oauth_adaptive_keeps_temperature_for_other_models(): + api_kwargs = {"model": "claude-3-7-sonnet", "temperature": 0.2} + _fix_temperature_for_oauth_adaptive(api_kwargs, site="test") + assert api_kwargs["temperature"] == 0.2 + + +def test_fix_temperature_for_oauth_adaptive_without_temperature_is_noop(): + api_kwargs = {"model": "claude-opus-4-6-20260101"} + _fix_temperature_for_oauth_adaptive(api_kwargs, site="test") + assert api_kwargs == {"model": "claude-opus-4-6-20260101"} diff --git a/tests/test_hook.py b/tests/test_hook.py new file mode 100644 index 0000000..4b27a2b --- /dev/null +++ b/tests/test_hook.py @@ -0,0 +1,101 @@ +# pyright: reportMissingImports=false, reportUnknownMemberType=false, reportUntypedFunctionDecorator=false, reportUnknownParameterType=false, reportMissingParameterType=false, reportUnusedParameter=false, reportArgumentType=false, reportCallIssue=false, reportUnknownVariableType=false, reportUnknownArgumentType=false, reportAttributeAccessIssue=false + +import importlib +import importlib.machinery +import importlib.util +import sys +import types + +import pytest + + +def _clear_bypass_finders(): + sys.meta_path[:] = [ + finder + for finder in sys.meta_path + if finder.__class__.__name__ != "_ClaudeCodeBypassFinder" + ] + + +@pytest.fixture +def hook_module(monkeypatch): + _clear_bypass_finders() + module = importlib.import_module("sitecustomize_hook") + module = importlib.reload(module) + _clear_bypass_finders() + yield module + _clear_bypass_finders() + + +def test_install_hook_registers_finder(hook_module): + hook_module._install_hook() + + assert any( + finder.__class__.__name__ == "_ClaudeCodeBypassFinder" + for finder in sys.meta_path + ) + + +def test_finder_only_targets_agent_anthropic_adapter(hook_module, monkeypatch): + calls = [] + + class Loader: + def exec_module(self, module): + module.loaded = True + + spec = importlib.machinery.ModuleSpec(hook_module._TARGET_MODULE, Loader()) + + def fake_find_spec(fullname): + calls.append(fullname) + return spec if fullname == hook_module._TARGET_MODULE else None + + monkeypatch.setattr(importlib.util, "find_spec", fake_find_spec) + hook_module._install_hook() + finder = next( + finder + for finder in sys.meta_path + if finder.__class__.__name__ == "_ClaudeCodeBypassFinder" + ) + + assert finder.find_spec("some.other.module") is None + found_spec = finder.find_spec(hook_module._TARGET_MODULE) + + assert found_spec is spec + assert calls == [hook_module._TARGET_MODULE] + + +def test_finder_sets_patched_flag_and_stops_repatching(hook_module, monkeypatch): + applied = [] + + class Loader: + def exec_module(self, module): + module.loaded = True + + spec = importlib.machinery.ModuleSpec(hook_module._TARGET_MODULE, Loader()) + + def fake_find_spec(fullname): + return spec if fullname == hook_module._TARGET_MODULE else None + + bypass_module = types.SimpleNamespace( + apply_patches=lambda module: applied.append(module.__name__) + ) + + monkeypatch.setattr(importlib.util, "find_spec", fake_find_spec) + monkeypatch.setitem(sys.modules, "anthropic_billing_bypass", bypass_module) + + hook_module._install_hook() + finder = next( + finder + for finder in sys.meta_path + if finder.__class__.__name__ == "_ClaudeCodeBypassFinder" + ) + + found_spec = finder.find_spec(hook_module._TARGET_MODULE) + assert found_spec is spec + + module = types.ModuleType(hook_module._TARGET_MODULE) + found_spec.loader.exec_module(module) + + assert finder._patched is True + assert applied == [hook_module._TARGET_MODULE] + assert finder.find_spec(hook_module._TARGET_MODULE) is None diff --git a/tests/test_signing.py b/tests/test_signing.py new file mode 100644 index 0000000..c953ea5 --- /dev/null +++ b/tests/test_signing.py @@ -0,0 +1,76 @@ +# pyright: reportPrivateUsage=false, reportUnknownParameterType=false, reportMissingParameterType=false, reportUnknownArgumentType=false, reportUnknownVariableType=false + +import hashlib + +from anthropic_billing_bypass import ( + _build_billing_header_value, + _compute_cch, + _compute_version_suffix, + _extract_first_user_message_text, +) + + +def test_extract_first_user_message_text_with_string_content(simple_messages): + assert _extract_first_user_message_text(simple_messages) == "hello world" + + +def test_extract_first_user_message_text_with_text_block(complex_messages): + assert _extract_first_user_message_text(complex_messages) == "hello world" + + +def test_extract_first_user_message_text_with_image_block_only_returns_empty_string(): + messages = [{"role": "user", "content": [{"type": "image", "source": {}}]}] + assert _extract_first_user_message_text(messages) == "" + + +def test_extract_first_user_message_text_with_no_user_message_returns_empty_string(): + messages = [{"role": "assistant", "content": "hello"}] + assert _extract_first_user_message_text(messages) == "" + + +def test_extract_first_user_message_text_uses_first_user_message_only(): + messages = [ + {"role": "user", "content": "first"}, + {"role": "user", "content": "second"}, + ] + assert _extract_first_user_message_text(messages) == "first" + + +def test_extract_first_user_message_text_with_empty_messages_returns_empty_string(): + assert _extract_first_user_message_text([]) == "" + + +def test_compute_cch_known_values(): + assert _compute_cch("hello world") == "b94d2" + assert _compute_cch("") == "e3b0c" + + +def test_compute_version_suffix_pads_short_text(): + expected = hashlib.sha256(b"59cf53e54c78e002.1.90").hexdigest()[:3] + assert _compute_version_suffix("abcde", "2.1.90") == expected + + +def test_compute_version_suffix_samples_long_enough_text(): + text = "abcdefghijklmnopqrstuvwxyz" + sampled = f"{text[4]}{text[7]}{text[20]}" + expected = hashlib.sha256( + f"59cf53e54c78{sampled}2.1.90".encode("utf-8") + ).hexdigest()[:3] + assert _compute_version_suffix(text, "2.1.90") == expected + + +def test_compute_version_suffix_known_value_for_hello_world(): + expected = hashlib.sha256(b"59cf53e54c78oo02.1.90").hexdigest()[:3] + assert _compute_version_suffix("hello world", "2.1.90") == expected + + +def test_build_billing_header_value_format(simple_messages): + version = "2.1.90" + entrypoint = "cli" + suffix = _compute_version_suffix("hello world", version) + cch = _compute_cch("hello world") + + assert _build_billing_header_value(simple_messages, version, entrypoint) == ( + f"x-anthropic-billing-header: cc_version={version}.{suffix}; " + f"cc_entrypoint={entrypoint}; cch={cch};" + )