Files

95 lines
2.8 KiB
Python

"""Tests for raycast_api.signing.hmac."""
from __future__ import annotations
import hashlib
import hmac as _hmac
import pytest
from raycast_api.signing.hmac import HMACSigner, encode_key, encode_output, hash_body
FAKE_SECRET = "DEAD" + "BEEF" * 15
class TestEncodeKey:
def test_utf8_passes_secret_through_as_bytes(self) -> None:
assert encode_key(FAKE_SECRET, "utf-8") == FAKE_SECRET.encode("utf-8")
def test_hex_decoding_supported_for_other_specs(self) -> None:
assert encode_key("deadbeef", "hex") == bytes.fromhex("deadbeef")
def test_unsupported_encoding_raises(self) -> None:
with pytest.raises(ValueError):
encode_key(FAKE_SECRET, "rot13")
class TestEncodeOutput:
def test_hex_lower(self) -> None:
assert encode_output(b"\xde\xad\xbe\xef", "hex-lower") == "deadbeef"
def test_hex_upper(self) -> None:
assert encode_output(b"\xde\xad\xbe\xef", "hex-upper") == "DEADBEEF"
def test_base64(self) -> None:
assert encode_output(b"\x00\x01\x02\x03", "base64") == "AAECAw=="
def test_unsupported_encoding_raises(self) -> None:
with pytest.raises(ValueError):
encode_output(b"abc", "rot13")
class TestHashBody:
def test_sha256_lowercase_hex(self) -> None:
assert hash_body(b"hello", "SHA-256") == hashlib.sha256(b"hello").hexdigest()
def test_empty_body_hash(self) -> None:
assert hash_body(b"", "SHA-256") == hashlib.sha256(b"").hexdigest()
def test_bad_algorithm(self) -> None:
with pytest.raises(ValueError):
hash_body(b"x", "MD-not-a-thing")
class TestHMACSigner:
def test_known_vector(self) -> None:
signer = HMACSigner(
FAKE_SECRET,
algorithm="SHA-256",
key_encoding="utf-8",
output_encoding="hex-lower",
)
message = b"some.canonical.string"
expected = _hmac.new(
FAKE_SECRET.encode("utf-8"), message, hashlib.sha256
).hexdigest()
assert signer.sign(message) == expected
def test_signer_is_reusable(self) -> None:
signer = HMACSigner(
FAKE_SECRET,
algorithm="SHA-256",
key_encoding="utf-8",
output_encoding="hex-lower",
)
a = signer.sign(b"first message")
b = signer.sign(b"second message")
assert a != b
assert signer.sign(b"first message") == a
def test_algorithm_name_is_normalised(self) -> None:
a = HMACSigner(
FAKE_SECRET,
algorithm="SHA-256",
key_encoding="utf-8",
output_encoding="hex-lower",
)
b = HMACSigner(
FAKE_SECRET,
algorithm="sha256",
key_encoding="utf-8",
output_encoding="hex-lower",
)
assert a.sign(b"x") == b.sign(b"x")