Tests: hold invoice tests pending during payment (#1839)
* tests: hold invoice tests pending during payment * sigh... * ok * hash preimage * preimage_hash == payment_hash * should error * check that payment is gone * cancel task while in-flight * lnbits endpoing return error * return error * add both options * fix list * respond to error * return false if payment status errors * outgoing invoice should be deleted after one status check * test api_payments_create error
This commit is contained in:
parent
1ab81f6d7e
commit
9f40b3cdbd
2 changed files with 110 additions and 7 deletions
|
|
@ -99,7 +99,7 @@ class LNbitsWallet(Wallet):
|
||||||
|
|
||||||
if r.is_error:
|
if r.is_error:
|
||||||
error_message = r.json()["detail"]
|
error_message = r.json()["detail"]
|
||||||
return PaymentResponse(None, None, None, None, error_message)
|
return PaymentResponse(False, None, None, None, error_message)
|
||||||
else:
|
else:
|
||||||
data = r.json()
|
data = r.json()
|
||||||
checking_id = data["payment_hash"]
|
checking_id = data["payment_hash"]
|
||||||
|
|
@ -124,7 +124,7 @@ class LNbitsWallet(Wallet):
|
||||||
r = await self.client.get(url=f"/api/v1/payments/{checking_id}")
|
r = await self.client.get(url=f"/api/v1/payments/{checking_id}")
|
||||||
|
|
||||||
if r.is_error:
|
if r.is_error:
|
||||||
return PaymentStatus(None)
|
return PaymentStatus(False)
|
||||||
data = r.json()
|
data = r.json()
|
||||||
if "paid" not in data and "details" not in data:
|
if "paid" not in data and "details" not in data:
|
||||||
return PaymentStatus(None)
|
return PaymentStatus(None)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ from lnbits.wallets import get_wallet_class
|
||||||
from tests.conftest import CreateInvoiceData, api_payments_create_invoice
|
from tests.conftest import CreateInvoiceData, api_payments_create_invoice
|
||||||
|
|
||||||
from ...helpers import (
|
from ...helpers import (
|
||||||
|
cancel_invoice,
|
||||||
get_random_invoice_data,
|
get_random_invoice_data,
|
||||||
is_fake,
|
is_fake,
|
||||||
pay_real_invoice,
|
pay_real_invoice,
|
||||||
|
|
@ -466,7 +467,9 @@ async def test_pay_real_invoice_set_pending_and_check_state(
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.skipif(is_fake, reason="this only works in regtest")
|
@pytest.mark.skipif(is_fake, reason="this only works in regtest")
|
||||||
async def test_pay_hold_invoice(client, hold_invoice, adminkey_headers_from):
|
async def test_pay_hold_invoice_check_pending(
|
||||||
|
client, hold_invoice, adminkey_headers_from
|
||||||
|
):
|
||||||
preimage, invoice = hold_invoice
|
preimage, invoice = hold_invoice
|
||||||
task = asyncio.create_task(
|
task = asyncio.create_task(
|
||||||
client.post(
|
client.post(
|
||||||
|
|
@ -477,15 +480,115 @@ async def test_pay_hold_invoice(client, hold_invoice, adminkey_headers_from):
|
||||||
)
|
)
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
# TODO: Proper test calle :)
|
# get payment hash from the invoice
|
||||||
# settle hold invoice
|
invoice_obj = bolt11.decode(invoice["payment_request"])
|
||||||
|
|
||||||
|
payment_db = await get_standalone_payment(invoice_obj.payment_hash)
|
||||||
|
|
||||||
|
assert payment_db
|
||||||
|
assert payment_db.pending is True
|
||||||
|
|
||||||
settle_invoice(preimage)
|
settle_invoice(preimage)
|
||||||
|
|
||||||
response = await task
|
response = await task
|
||||||
assert response.status_code < 300
|
assert response.status_code < 300
|
||||||
|
|
||||||
# check if paid
|
# check if paid
|
||||||
# randomly cancel invoice
|
|
||||||
# cancel_invoice(invoice["payment_hash"])
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
payment_db_after_settlement = await get_standalone_payment(invoice_obj.payment_hash)
|
||||||
|
|
||||||
|
assert payment_db_after_settlement
|
||||||
|
assert payment_db_after_settlement.pending is False
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.skipif(is_fake, reason="this only works in regtest")
|
||||||
|
async def test_pay_hold_invoice_check_pending_and_fail(
|
||||||
|
client, hold_invoice, adminkey_headers_from
|
||||||
|
):
|
||||||
|
preimage, invoice = hold_invoice
|
||||||
|
task = asyncio.create_task(
|
||||||
|
client.post(
|
||||||
|
"/api/v1/payments",
|
||||||
|
json={"bolt11": invoice["payment_request"]},
|
||||||
|
headers=adminkey_headers_from,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
# get payment hash from the invoice
|
||||||
|
invoice_obj = bolt11.decode(invoice["payment_request"])
|
||||||
|
|
||||||
|
payment_db = await get_standalone_payment(invoice_obj.payment_hash)
|
||||||
|
|
||||||
|
assert payment_db
|
||||||
|
assert payment_db.pending is True
|
||||||
|
|
||||||
|
preimage_hash = hashlib.sha256(bytes.fromhex(preimage)).hexdigest()
|
||||||
|
|
||||||
|
# cancel the hodl invoice
|
||||||
|
assert preimage_hash == invoice_obj.payment_hash
|
||||||
|
cancel_invoice(preimage_hash)
|
||||||
|
|
||||||
|
response = await task
|
||||||
|
assert response.status_code > 300 # should error
|
||||||
|
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
# payment should not be in database anymore
|
||||||
|
payment_db_after_settlement = await get_standalone_payment(invoice_obj.payment_hash)
|
||||||
|
assert payment_db_after_settlement is None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.skipif(is_fake, reason="this only works in regtest")
|
||||||
|
async def test_pay_hold_invoice_check_pending_and_fail_cancel_payment_task_in_meantime(
|
||||||
|
client, hold_invoice, adminkey_headers_from
|
||||||
|
):
|
||||||
|
preimage, invoice = hold_invoice
|
||||||
|
task = asyncio.create_task(
|
||||||
|
client.post(
|
||||||
|
"/api/v1/payments",
|
||||||
|
json={"bolt11": invoice["payment_request"]},
|
||||||
|
headers=adminkey_headers_from,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
# get payment hash from the invoice
|
||||||
|
invoice_obj = bolt11.decode(invoice["payment_request"])
|
||||||
|
|
||||||
|
payment_db = await get_standalone_payment(invoice_obj.payment_hash)
|
||||||
|
|
||||||
|
assert payment_db
|
||||||
|
assert payment_db.pending is True
|
||||||
|
|
||||||
|
# cancel payment task, this simulates the client dropping the connection
|
||||||
|
task.cancel()
|
||||||
|
|
||||||
|
preimage_hash = hashlib.sha256(bytes.fromhex(preimage)).hexdigest()
|
||||||
|
|
||||||
|
assert preimage_hash == invoice_obj.payment_hash
|
||||||
|
cancel_invoice(preimage_hash)
|
||||||
|
|
||||||
|
# check if paid
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
# payment should still be in db
|
||||||
|
payment_db_after_settlement = await get_standalone_payment(invoice_obj.payment_hash)
|
||||||
|
assert payment_db_after_settlement is not None
|
||||||
|
|
||||||
|
# status should still be available and be False
|
||||||
|
status = await payment_db.check_status()
|
||||||
|
assert status.paid is False
|
||||||
|
|
||||||
|
# now the payment should be gone after the status check
|
||||||
|
payment_db_after_status_check = await get_standalone_payment(
|
||||||
|
invoice_obj.payment_hash
|
||||||
|
)
|
||||||
|
assert payment_db_after_status_check is None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue