forked from Rockachopa/Timmy-time-dashboard
111 lines
3.9 KiB
Python
111 lines
3.9 KiB
Python
|
|
"""Tests for the L402 proxy and payment handler."""
|
||
|
|
|
||
|
|
import hashlib
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
|
||
|
|
# ── Payment Handler ──────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
def test_create_invoice():
|
||
|
|
from timmy_serve.payment_handler import PaymentHandler
|
||
|
|
handler = PaymentHandler()
|
||
|
|
invoice = handler.create_invoice(100, "test payment")
|
||
|
|
assert invoice.amount_sats == 100
|
||
|
|
assert invoice.memo == "test payment"
|
||
|
|
assert invoice.payment_hash is not None
|
||
|
|
assert invoice.payment_request.startswith("lnbc")
|
||
|
|
|
||
|
|
|
||
|
|
def test_check_payment_mock_auto_settles():
|
||
|
|
from timmy_serve.payment_handler import PaymentHandler
|
||
|
|
handler = PaymentHandler()
|
||
|
|
invoice = handler.create_invoice(50, "auto settle")
|
||
|
|
assert handler.check_payment(invoice.payment_hash) is True
|
||
|
|
|
||
|
|
|
||
|
|
def test_check_payment_nonexistent():
|
||
|
|
from timmy_serve.payment_handler import PaymentHandler
|
||
|
|
handler = PaymentHandler()
|
||
|
|
assert handler.check_payment("nonexistent-hash") is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_settle_invoice_with_preimage():
|
||
|
|
from timmy_serve.payment_handler import PaymentHandler
|
||
|
|
handler = PaymentHandler()
|
||
|
|
invoice = handler.create_invoice(75, "preimage test")
|
||
|
|
invoice.settled = False # Reset for manual settlement
|
||
|
|
assert handler.settle_invoice(invoice.payment_hash, invoice.preimage) is True
|
||
|
|
assert invoice.settled is True
|
||
|
|
|
||
|
|
|
||
|
|
def test_settle_invoice_wrong_preimage():
|
||
|
|
from timmy_serve.payment_handler import PaymentHandler
|
||
|
|
handler = PaymentHandler()
|
||
|
|
invoice = handler.create_invoice(75, "wrong preimage")
|
||
|
|
invoice.settled = False
|
||
|
|
assert handler.settle_invoice(invoice.payment_hash, "0" * 64) is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_list_invoices():
|
||
|
|
from timmy_serve.payment_handler import PaymentHandler
|
||
|
|
handler = PaymentHandler()
|
||
|
|
handler.create_invoice(10, "a")
|
||
|
|
handler.create_invoice(20, "b")
|
||
|
|
assert len(handler.list_invoices()) == 2
|
||
|
|
|
||
|
|
|
||
|
|
def test_list_invoices_settled_only():
|
||
|
|
from timmy_serve.payment_handler import PaymentHandler
|
||
|
|
handler = PaymentHandler()
|
||
|
|
inv = handler.create_invoice(10, "settle me")
|
||
|
|
handler.check_payment(inv.payment_hash) # auto-settles in mock
|
||
|
|
settled = handler.list_invoices(settled_only=True)
|
||
|
|
assert len(settled) >= 1
|
||
|
|
|
||
|
|
|
||
|
|
def test_get_invoice():
|
||
|
|
from timmy_serve.payment_handler import PaymentHandler
|
||
|
|
handler = PaymentHandler()
|
||
|
|
inv = handler.create_invoice(100, "get me")
|
||
|
|
found = handler.get_invoice(inv.payment_hash)
|
||
|
|
assert found is not None
|
||
|
|
assert found.amount_sats == 100
|
||
|
|
|
||
|
|
|
||
|
|
# ── L402 Proxy ───────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
def test_create_l402_challenge():
|
||
|
|
from timmy_serve.l402_proxy import create_l402_challenge
|
||
|
|
challenge = create_l402_challenge(100, "API access")
|
||
|
|
assert "macaroon" in challenge
|
||
|
|
assert "invoice" in challenge
|
||
|
|
assert "payment_hash" in challenge
|
||
|
|
|
||
|
|
|
||
|
|
def test_verify_l402_token_valid():
|
||
|
|
from timmy_serve.l402_proxy import create_l402_challenge, verify_l402_token
|
||
|
|
challenge = create_l402_challenge(50, "verify test")
|
||
|
|
# In mock mode, payment auto-settles
|
||
|
|
assert verify_l402_token(challenge["macaroon"]) is True
|
||
|
|
|
||
|
|
|
||
|
|
def test_verify_l402_token_invalid_format():
|
||
|
|
from timmy_serve.l402_proxy import verify_l402_token
|
||
|
|
assert verify_l402_token("not-a-valid-token") is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_macaroon_roundtrip():
|
||
|
|
from timmy_serve.l402_proxy import Macaroon
|
||
|
|
mac = Macaroon(identifier="test-id", signature="test-sig")
|
||
|
|
serialized = mac.serialize()
|
||
|
|
restored = Macaroon.deserialize(serialized)
|
||
|
|
assert restored is not None
|
||
|
|
assert restored.identifier == "test-id"
|
||
|
|
assert restored.signature == "test-sig"
|
||
|
|
|
||
|
|
|
||
|
|
def test_macaroon_deserialize_invalid():
|
||
|
|
from timmy_serve.l402_proxy import Macaroon
|
||
|
|
assert Macaroon.deserialize("garbage") is None
|