Files
raycast-api/tests/test_transforms.py
T

59 lines
2.0 KiB
Python

"""Tests for raycast_api.signing.transforms."""
from __future__ import annotations
import pytest
from raycast_api.signing.transforms import apply_rot
from raycast_api.signing_spec import RotRange
RAYCAST_RANGES = [
RotRange(0x41, 0x5A, 13),
RotRange(0x61, 0x7A, 13),
RotRange(0x30, 0x39, 5),
]
class TestRaycastDefaults:
def test_letter_rotation_matches_handoff(self) -> None:
assert apply_rot("abcXYZ", RAYCAST_RANGES) == "nopKLM"
def test_digit_rotation(self) -> None:
assert apply_rot("01234", RAYCAST_RANGES) == "56789"
assert apply_rot("56789", RAYCAST_RANGES) == "01234"
def test_punctuation_unchanged(self) -> None:
assert apply_rot("a.b", RAYCAST_RANGES) == "n.o"
assert apply_rot(":/?-_=", RAYCAST_RANGES) == ":/?-_="
def test_double_apply_is_identity_for_letters_and_hex_digits(self) -> None:
sample = "deadbeef0123456789"
assert apply_rot(apply_rot(sample, RAYCAST_RANGES), RAYCAST_RANGES) == sample
def test_empty_string(self) -> None:
assert apply_rot("", RAYCAST_RANGES) == ""
def test_unicode_outside_ranges_passes_through(self) -> None:
assert apply_rot("café→", RAYCAST_RANGES) == "pnsé→"
class TestArbitraryRanges:
def test_single_range_no_overflow(self) -> None:
assert apply_rot("ABCXYZ", [RotRange(0x41, 0x5A, 0)]) == "ABCXYZ"
def test_shift_wraps(self) -> None:
assert apply_rot("hello", [RotRange(0x61, 0x7A, 26)]) == "hello"
assert apply_rot("abz", [RotRange(0x61, 0x7A, 1)]) == "bca"
def test_first_matching_range_wins(self) -> None:
ranges = [RotRange(0x61, 0x7A, 1), RotRange(0x61, 0x7A, 5)]
assert apply_rot("a", ranges) == "b"
def test_range_outside_input_does_nothing(self) -> None:
assert apply_rot("hello", [RotRange(0x30, 0x39, 5)]) == "hello"
def test_negative_shift_rejected_at_construction(self) -> None:
with pytest.raises(ValueError):
RotRange(0x41, 0x5A, -1)