diff --git a/tests/regtest/test_real_hold_invoice.py b/tests/regtest/test_real_hold_invoice.py index bd188a472..1100d1cc1 100644 --- a/tests/regtest/test_real_hold_invoice.py +++ b/tests/regtest/test_real_hold_invoice.py @@ -1,16 +1,19 @@ -import hashlib -import os +import asyncio import pytest +from lnbits.core.models import Payment from lnbits.core.services.payments import ( cancel_hold_invoice, create_invoice, + get_standalone_payment, settle_hold_invoice, ) from lnbits.exceptions import InvoiceError +from lnbits.utils.crypto import random_secret_and_hash from ..helpers import funding_source, is_fake +from .helpers import pay_real_invoice @pytest.mark.anyio @@ -21,6 +24,14 @@ from ..helpers import funding_source, is_fake ) async def test_pay_raise_unsupported(app): payment_hash = "0" * 32 + payment = Payment( + checking_id=payment_hash, + amount=1000, + wallet_id="fake_wallet_id", + bolt11="fake_holdinvoice", + payment_hash=payment_hash, + fee=0, + ) with pytest.raises(InvoiceError): await create_invoice( wallet_id="fake_wallet_id", @@ -29,31 +40,79 @@ async def test_pay_raise_unsupported(app): payment_hash=payment_hash, ) with pytest.raises(InvoiceError): - await settle_hold_invoice(preimage=payment_hash) + await settle_hold_invoice(payment, payment_hash) with pytest.raises(InvoiceError): - await cancel_hold_invoice(payment_hash) + await cancel_hold_invoice(payment) @pytest.mark.anyio @pytest.mark.skipif(is_fake, reason="this only works in regtest") @pytest.mark.skipif( - funding_source.__class__.__name__ not in ["LndRestWallet"], + funding_source.__class__.__name__ not in ["LndRestWallet", "LndWallet"], reason="this only works for lndrest", ) -async def test_pay_real_hold_invoice(app, from_wallet): +async def test_cancel_real_hold_invoice(app, from_wallet): - preimage = os.urandom(32) - preimage_hash = hashlib.sha256(preimage).hexdigest() + _, payment_hash = random_secret_and_hash() payment = await create_invoice( wallet_id=from_wallet.id, amount=1000, - memo="test_holdinvoice", - payment_hash=preimage_hash, + memo="test_cancel_holdinvoice", + payment_hash=payment_hash, ) assert payment.amount == 1000 * 1000 - assert payment.memo == "test_holdinvoice" + assert payment.memo == "test_cancel_holdinvoice" assert payment.status == "pending" assert payment.wallet_id == from_wallet.id - payment = await cancel_hold_invoice(payment_hash=preimage_hash) - assert payment.status == "failed" + payment = await cancel_hold_invoice(payment=payment) + assert payment.ok is True + + updated_payment = await get_standalone_payment(payment_hash, incoming=True) + + assert updated_payment + assert updated_payment.status == "failed" + + +@pytest.mark.anyio +@pytest.mark.skipif(is_fake, reason="this only works in regtest") +@pytest.mark.skipif( + funding_source.__class__.__name__ not in ["LndRestWallet", "LndWallet"], + reason="this only works for lndrest", +) +async def test_settle_real_hold_invoice(app, from_wallet): + + preimage, payment_hash = random_secret_and_hash() + payment = await create_invoice( + wallet_id=from_wallet.id, + amount=1000, + memo="test_settle_holdinvoice", + payment_hash=payment_hash, + ) + assert payment.amount == 1000 * 1000 + assert payment.memo == "test_settle_holdinvoice" + assert payment.status == "pending" + assert payment.wallet_id == from_wallet.id + + # invoice should still be open + with pytest.raises(InvoiceError): + await settle_hold_invoice(payment=payment, preimage=preimage) + + def pay_invoice(): + pay_real_invoice(payment.bolt11) + + async def settle(): + await asyncio.sleep(1) + invoice_response = await settle_hold_invoice(payment=payment, preimage=preimage) + assert invoice_response.ok is True + + coro = asyncio.to_thread(pay_invoice) + task = asyncio.create_task(coro) + await asyncio.gather(task, settle()) + + await asyncio.sleep(1) + + updated_payment = await get_standalone_payment(payment_hash, incoming=True) + + assert updated_payment + assert updated_payment.status == "success"