From 3ac6a98adc83d183a217165674dadf80845296ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Wed, 1 Feb 2023 16:54:07 +0100 Subject: [PATCH] TEST: add helpers and a test to pay external invoice (#1414) * add helpers and a test to pay external invoice * skip real test in fakewallet * formatting * fix test * formatting --- tests/conftest.py | 9 ++++++- tests/core/views/test_api.py | 23 ++++++++++++++++- tests/helpers.py | 50 +++++++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 6bcb463fe..69dca09c9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,7 +9,7 @@ from lnbits.core.crud import create_account, create_wallet from lnbits.core.views.api import CreateInvoiceData, api_payments_create_invoice from lnbits.db import Database from lnbits.settings import settings -from tests.helpers import credit_wallet, get_random_invoice_data +from tests.helpers import credit_wallet, get_random_invoice_data, get_real_invoice @pytest_asyncio.fixture(scope="session") @@ -123,3 +123,10 @@ async def invoice(to_wallet): invoice = await api_payments_create_invoice(invoiceData, to_wallet) yield invoice del invoice + + +@pytest_asyncio.fixture(scope="session") +async def real_invoice(): + invoice = get_real_invoice(100_000, "test-fixture") + yield invoice + del invoice diff --git a/tests/core/views/test_api.py b/tests/core/views/test_api.py index d62936198..51d2fe606 100644 --- a/tests/core/views/test_api.py +++ b/tests/core/views/test_api.py @@ -6,7 +6,7 @@ from lnbits import bolt11 from lnbits.core.views.api import api_payment from lnbits.settings import get_wallet_class -from ...helpers import get_random_invoice_data, is_regtest +from ...helpers import get_random_invoice_data, is_fake, is_regtest WALLET = get_wallet_class() @@ -254,3 +254,24 @@ async def test_create_invoice_with_unhashed_description(client, inkey_headers_to assert invoice_bolt11.description_hash == descr_hash assert invoice_bolt11.description is None return invoice + + +@pytest.mark.asyncio +@pytest.mark.skipif(is_fake, reason="this only works in regtest") +async def test_pay_real_invoice( + client, real_invoice, adminkey_headers_from, inkey_headers_from +): + response = await client.post( + "/api/v1/payments", json=real_invoice, headers=adminkey_headers_from + ) + assert response.status_code < 300 + invoice = response.json() + assert len(invoice["payment_hash"]) == 64 + assert len(invoice["checking_id"]) > 0 + + # check the payment status + response = await api_payment( + invoice["payment_hash"], inkey_headers_from["X-Api-Key"] + ) + assert type(response) == dict + assert response["paid"] == True diff --git a/tests/helpers.py b/tests/helpers.py index 9d2aae722..7aceabc80 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -1,7 +1,10 @@ import hashlib +import json import random import secrets import string +import time +from subprocess import PIPE, Popen, run from lnbits.core.crud import create_payment from lnbits.settings import get_wallet_class @@ -24,7 +27,7 @@ async def credit_wallet(wallet_id: str, amount: int): ) -def get_random_string(N=10): +def get_random_string(N: int = 10): return "".join( random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N) @@ -38,3 +41,48 @@ async def get_random_invoice_data(): WALLET = get_wallet_class() is_fake: bool = WALLET.__class__.__name__ == "FakeWallet" is_regtest: bool = not is_fake + + +docker_bitcoin_rpc = "lnbits" +docker_prefix = "lnbits-legend" +docker_cmd = f"docker exec" + +docker_lightning = f"{docker_cmd} {docker_prefix}-clightning-2-1" +docker_lightning_cli = f"{docker_lightning} lightning-cli --network regtest" + +docker_bitcoin = f"{docker_cmd} {docker_prefix}-bitcoind-1-1" +docker_bitcoin_cli = f"{docker_bitcoin} bitcoin-cli -rpcuser={docker_bitcoin_rpc} -rpcpassword={docker_bitcoin_rpc} -regtest" + + +def run_cmd(cmd: str) -> str: + return run(cmd, shell=True, capture_output=True).stdout.decode("UTF-8").strip() + + +def run_cmd_json(cmd: str) -> dict: + return json.loads(run_cmd(cmd)) + + +def get_real_invoice(sats: int, prefix: str, description: str = "test") -> dict: + msats = sats * 1000 + return run_cmd_json( + f"{docker_lightning_cli} invoice {msats} {prefix}-{time.time()} {description}" + ) + + +def pay_real_invoice(invoice: str) -> Popen: + return Popen( + f"{docker_lightning_cli} pay {invoice}", shell=True, stdin=PIPE, stdout=PIPE + ) + + +def mine_blocks(blocks: int = 1) -> str: + return run_cmd(f"{docker_bitcoin_cli} -generate {blocks}") + + +def create_onchain_address(address_type: str = "bech32") -> str: + return run_cmd(f"{docker_bitcoin_cli} getnewaddress {address_type}") + + +def pay_onchain(address: str, sats: int) -> str: + btc = sats * 0.00000001 + return run_cmd(f"{docker_bitcoin_cli} sendtoaddress {address} {btc}")