tests: add more lnurl testing for PaymentIdentifier
adds some more detailed tests to `test_payment_identifier.py` to test lnurlp and lnurlw separately and mock their resolve.
This commit is contained in:
@@ -1,9 +1,13 @@
|
|||||||
import os
|
import os
|
||||||
|
import asyncio
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from electrum import SimpleConfig
|
from electrum import SimpleConfig
|
||||||
from electrum.invoices import Invoice
|
from electrum.invoices import Invoice
|
||||||
from electrum.payment_identifier import (maybe_extract_lightning_payment_identifier, PaymentIdentifier,
|
from electrum.payment_identifier import (maybe_extract_lightning_payment_identifier, PaymentIdentifier,
|
||||||
PaymentIdentifierType, invoice_from_payment_identifier)
|
PaymentIdentifierType, PaymentIdentifierState,
|
||||||
|
invoice_from_payment_identifier)
|
||||||
|
from electrum.lnurl import LNURL6Data, LNURL3Data, LNURLError
|
||||||
from electrum.transaction import PartialTxOutput
|
from electrum.transaction import PartialTxOutput
|
||||||
|
|
||||||
from . import ElectrumTestCase
|
from . import ElectrumTestCase
|
||||||
@@ -143,14 +147,112 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
|||||||
pi = PaymentIdentifier(None, bip21)
|
pi = PaymentIdentifier(None, bip21)
|
||||||
self.assertFalse(pi.is_valid())
|
self.assertFalse(pi.is_valid())
|
||||||
|
|
||||||
def test_lnurl(self):
|
def test_lnurl_basic(self):
|
||||||
lnurl = 'lnurl1dp68gurn8ghj7um9wfmxjcm99e5k7telwy7nxenrxvmrgdtzxsenjcm98pjnwxq96s9'
|
"""Test basic LNURL parsing without resolve"""
|
||||||
pi = PaymentIdentifier(None, lnurl)
|
valid_lnurl = 'lnurl1dp68gurn8ghj7um9wfmxjcm99e5k7telwy7nxenrxvmrgdtzxsenjcm98pjnwxq96s9'
|
||||||
|
pi = PaymentIdentifier(None, valid_lnurl)
|
||||||
self.assertTrue(pi.is_valid())
|
self.assertTrue(pi.is_valid())
|
||||||
|
self.assertEqual(PaymentIdentifierType.LNURL, pi.type)
|
||||||
self.assertFalse(pi.is_available())
|
self.assertFalse(pi.is_available())
|
||||||
self.assertTrue(pi.need_resolve())
|
self.assertTrue(pi.need_resolve())
|
||||||
|
self.assertEqual(PaymentIdentifierState.NEED_RESOLVE, pi.state)
|
||||||
|
|
||||||
# TODO: resolve mock
|
# Test with lightning: prefix
|
||||||
|
lightning_lnurl = f'lightning:{valid_lnurl}'
|
||||||
|
pi = PaymentIdentifier(None, lightning_lnurl)
|
||||||
|
self.assertTrue(pi.is_valid())
|
||||||
|
self.assertEqual(PaymentIdentifierType.LNURL, pi.type)
|
||||||
|
self.assertTrue(pi.need_resolve())
|
||||||
|
|
||||||
|
@patch('electrum.payment_identifier.request_lnurl')
|
||||||
|
def test_lnurl_pay_resolve(self, mock_request_lnurl):
|
||||||
|
"""Test LNURL-pay (LNURL6) with mocked resolve"""
|
||||||
|
valid_lnurl = 'LNURL1DP68GURN8GHJ7MRWVF5HGUEWD3HXZERYWFJHXUEWVDHK6TMVDE6HYMRS9ANRV46DXETQPJQCS4'
|
||||||
|
|
||||||
|
# Mock lnurl-p response
|
||||||
|
mock_lnurl6_data = LNURL6Data(
|
||||||
|
callback_url='https://example.com/lnurl-pay',
|
||||||
|
max_sendable_sat=1_000_000,
|
||||||
|
min_sendable_sat=1_000,
|
||||||
|
metadata_plaintext='Test payment',
|
||||||
|
comment_allowed=100,
|
||||||
|
)
|
||||||
|
mock_request_lnurl.return_value = mock_lnurl6_data
|
||||||
|
|
||||||
|
pi = PaymentIdentifier(None, valid_lnurl)
|
||||||
|
self.assertTrue(pi.need_resolve())
|
||||||
|
self.assertEqual(PaymentIdentifierType.LNURL, pi.type)
|
||||||
|
|
||||||
|
async def run_resolve():
|
||||||
|
await pi._do_resolve()
|
||||||
|
|
||||||
|
asyncio.run(run_resolve())
|
||||||
|
|
||||||
|
self.assertEqual(PaymentIdentifierType.LNURLP, pi.type)
|
||||||
|
self.assertEqual(PaymentIdentifierState.LNURLP_FINALIZE, pi.state)
|
||||||
|
self.assertTrue(pi.need_finalize())
|
||||||
|
self.assertIsNotNone(pi.lnurl_data)
|
||||||
|
self.assertTrue(isinstance(pi.lnurl_data, LNURL6Data))
|
||||||
|
self.assertEqual(1_000, pi.lnurl_data.min_sendable_sat)
|
||||||
|
self.assertEqual(1_000_000, pi.lnurl_data.max_sendable_sat)
|
||||||
|
self.assertEqual('Test payment', pi.lnurl_data.metadata_plaintext)
|
||||||
|
self.assertEqual(100, pi.lnurl_data.comment_allowed)
|
||||||
|
|
||||||
|
@patch('electrum.payment_identifier.request_lnurl')
|
||||||
|
def test_lnurl_withdraw_resolve(self, mock_request_lnurl):
|
||||||
|
"""Test LNURL-withdraw (LNURL3) with mocked resolve"""
|
||||||
|
valid_lnurl = 'LNURL1DP68GURN8GHJ7MRWVF5HGUEWD3HXZERYWFJHXUEWVDHK6TM4WPNHYCTYV4EJ7DFCVGENSDPH8QCRZETXVGCXGCMPVFJR' \
|
||||||
|
'WENP8P3NJEP3XE3NQWRPXFJR2VRRVSCX2V33V5UNVC3SXP3RXCFSVFSKVWPCV3SKZWTP8YUZ7AMFW35XGUNPWUHKZURF9AMRZT' \
|
||||||
|
'MVDE6HYMP0FETHVUNZDAMHQ7JSF4RX73TZ2VU9Z3J3GVMSLCJ57F'
|
||||||
|
|
||||||
|
# Mock lnurl-w response
|
||||||
|
mock_lnurl3_data = LNURL3Data(
|
||||||
|
callback_url='https://example.com/lnurl-withdraw',
|
||||||
|
k1='test-k1-value',
|
||||||
|
default_description='Test withdrawal',
|
||||||
|
min_withdrawable_sat=1_000,
|
||||||
|
max_withdrawable_sat=500_000,
|
||||||
|
)
|
||||||
|
mock_request_lnurl.return_value = mock_lnurl3_data
|
||||||
|
|
||||||
|
pi = PaymentIdentifier(None, valid_lnurl)
|
||||||
|
self.assertTrue(pi.need_resolve())
|
||||||
|
self.assertEqual(PaymentIdentifierType.LNURL, pi.type)
|
||||||
|
|
||||||
|
async def run_resolve():
|
||||||
|
await pi._do_resolve()
|
||||||
|
|
||||||
|
asyncio.run(run_resolve())
|
||||||
|
|
||||||
|
self.assertEqual(PaymentIdentifierType.LNURLW, pi.type)
|
||||||
|
self.assertEqual(PaymentIdentifierState.LNURLW_FINALIZE, pi.state)
|
||||||
|
self.assertIsNotNone(pi.lnurl_data)
|
||||||
|
self.assertEqual('test-k1-value', pi.lnurl_data.k1)
|
||||||
|
self.assertEqual('Test withdrawal', pi.lnurl_data.default_description)
|
||||||
|
self.assertEqual(1000, pi.lnurl_data.min_withdrawable_sat)
|
||||||
|
self.assertEqual(500000, pi.lnurl_data.max_withdrawable_sat)
|
||||||
|
|
||||||
|
@patch('electrum.payment_identifier.request_lnurl')
|
||||||
|
def test_lnurl_resolve_error(self, mock_request_lnurl):
|
||||||
|
"""Test LNURL resolve error handling"""
|
||||||
|
lnurl = 'LNURL1DP68GURN8GHJ7MRWVF5HGUEWD3HXZERYWFJHXUEWVDHK6TM4WPNHYCTYV4EJ7DFCVGENSDPH8QCRZETXVGCXGCMPVFJR' \
|
||||||
|
'WENP8P3NJEP3XE3NQWRPXFJR2VRRVSCX2V33V5UNVC3SXP3RXCFSVFSKVWPCV3SKZWTP8YUZ7AMFW35XGUNPWUHKZURF9AMRZT' \
|
||||||
|
'MVDE6HYMP0FETHVUNZDAMHQ7JSF4RX73TZ2VU9Z3J3GVMSLCJ57F'
|
||||||
|
|
||||||
|
# Mock LNURL error
|
||||||
|
mock_request_lnurl.side_effect = LNURLError("Server error")
|
||||||
|
|
||||||
|
pi = PaymentIdentifier(None, lnurl)
|
||||||
|
self.assertTrue(pi.need_resolve())
|
||||||
|
|
||||||
|
async def run_resolve():
|
||||||
|
await pi._do_resolve()
|
||||||
|
|
||||||
|
asyncio.run(run_resolve())
|
||||||
|
|
||||||
|
self.assertEqual(PaymentIdentifierState.ERROR, pi.state)
|
||||||
|
self.assertTrue(pi.is_error())
|
||||||
|
self.assertIn("Server error", pi.get_error())
|
||||||
|
|
||||||
def test_multiline(self):
|
def test_multiline(self):
|
||||||
pi_str = '\n'.join([
|
pi_str = '\n'.join([
|
||||||
|
|||||||
Reference in New Issue
Block a user