Co-authored-by: Kimi Agent <kimi@timmy.local> Co-committed-by: Kimi Agent <kimi@timmy.local>
110 lines
3.5 KiB
Python
110 lines
3.5 KiB
Python
"""Unit tests for the lightning package (factory + ledger)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from lightning.factory import Invoice, MockBackend, get_backend
|
|
from lightning.ledger import (
|
|
TxStatus,
|
|
TxType,
|
|
clear,
|
|
create_invoice_entry,
|
|
get_balance,
|
|
get_transactions,
|
|
mark_settled,
|
|
)
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _clean_ledger():
|
|
"""Reset the in-memory ledger between tests."""
|
|
clear()
|
|
yield
|
|
clear()
|
|
|
|
|
|
# ── Factory tests ────────────────────────────────────────────────────
|
|
|
|
|
|
class TestMockBackend:
|
|
def test_create_invoice_returns_invoice(self):
|
|
backend = MockBackend()
|
|
inv = backend.create_invoice(100, "test memo")
|
|
assert isinstance(inv, Invoice)
|
|
assert inv.amount_sats == 100
|
|
assert inv.memo == "test memo"
|
|
assert len(inv.payment_hash) == 64 # SHA-256 hex
|
|
assert inv.payment_request.startswith("lnbc")
|
|
|
|
def test_invoices_have_unique_hashes(self):
|
|
backend = MockBackend()
|
|
a = backend.create_invoice(10)
|
|
b = backend.create_invoice(10)
|
|
assert a.payment_hash != b.payment_hash
|
|
|
|
|
|
class TestGetBackend:
|
|
def test_returns_mock_backend(self):
|
|
backend = get_backend()
|
|
assert isinstance(backend, MockBackend)
|
|
|
|
|
|
# ── Ledger tests ─────────────────────────────────────────────────────
|
|
|
|
|
|
class TestLedger:
|
|
def test_create_invoice_entry(self):
|
|
entry = create_invoice_entry(
|
|
payment_hash="abc123",
|
|
amount_sats=500,
|
|
memo="test",
|
|
source="unit_test",
|
|
)
|
|
assert entry.tx_type == TxType.incoming
|
|
assert entry.status == TxStatus.pending
|
|
assert entry.amount_sats == 500
|
|
|
|
def test_mark_settled(self):
|
|
create_invoice_entry(payment_hash="hash1", amount_sats=100)
|
|
result = mark_settled("hash1", preimage="secret")
|
|
assert result is not None
|
|
assert result.status == TxStatus.settled
|
|
assert result.preimage == "secret"
|
|
assert result.settled_at != ""
|
|
|
|
def test_mark_settled_unknown_hash(self):
|
|
assert mark_settled("nonexistent") is None
|
|
|
|
def test_get_balance_empty(self):
|
|
bal = get_balance()
|
|
assert bal["net_sats"] == 0
|
|
assert bal["available_sats"] == 0
|
|
|
|
def test_get_balance_with_settled(self):
|
|
create_invoice_entry(payment_hash="h1", amount_sats=1000)
|
|
mark_settled("h1")
|
|
bal = get_balance()
|
|
assert bal["incoming_total_sats"] == 1000
|
|
assert bal["net_sats"] == 1000
|
|
assert bal["available_sats"] == 1000
|
|
|
|
def test_get_balance_pending_not_counted(self):
|
|
create_invoice_entry(payment_hash="h2", amount_sats=500)
|
|
bal = get_balance()
|
|
assert bal["incoming_total_sats"] == 0
|
|
assert bal["pending_incoming_sats"] == 500
|
|
|
|
def test_get_transactions_returns_entries(self):
|
|
create_invoice_entry(payment_hash="t1", amount_sats=10)
|
|
create_invoice_entry(payment_hash="t2", amount_sats=20)
|
|
txs = get_transactions()
|
|
assert len(txs) == 2
|
|
|
|
def test_get_transactions_filter_by_status(self):
|
|
create_invoice_entry(payment_hash="f1", amount_sats=10)
|
|
create_invoice_entry(payment_hash="f2", amount_sats=20)
|
|
mark_settled("f1")
|
|
assert len(get_transactions(status="settled")) == 1
|
|
assert len(get_transactions(status="pending")) == 1
|