mirror of
https://github.com/lnbits/lnbits.git
synced 2025-06-27 01:01:02 +02:00
test: add tests for alby (#2390)
* test: initial commit * chore: code format * fix: comment out bad `status.pending` (to be fixed in core) * fix: 404 tests * test: extract first `create_invoice` test * chore: reminder * add: error test * chore: experiment * feat: adapt parsing * refactor: data structure * fix: some tests * fix: make response uniform * fix: test data * chore: clean-up * fix: uniform responses * fix: user agent * fix: user agent * fix: user-agent again * test: add `with error` test * feat: customize test name * fix: better exception handling for `status` * fix: add `try-catch` for `raise_for_status` * test: with no mocks * chore: clean-up generalized tests * chore: code format * chore: code format * chore: remove extracted tests * test: add `create_invoice`: error test * add: test for `create_invoice` with http 404 * test: extract `test_pay_invoice_ok` * test: extract `test_pay_invoice_error_response` * test: extract `test_pay_invoice_http_404` * test: add "missing data" * test: add `bad-json` * test: add `no mocks` for `create_invoice` * test: add `no mocks` for `pay_invoice` * test: add `bad json` tests * chore: re-order tests * test: add `missing data` test for `pay_imvoice` * chore: re-order tests * test: add `success` test for `get_invoice_status ` * feat: update test structure * test: new status * test: add more test * chore: code clean-up * test: add success test for `get_payment_status ` * test: add `pending` tests for `check_payment_status` * chore: remove extracted tests * test: add more tests * test: add `no mocks` test * fix: funding source loading * refactor: start to extract data model * chore: final clean-up * chore: rename file * test: add tests for alby * refactor: `KeyError` handling * chore: log error * chore: skip the negative fee test * fix: error message fetching
This commit is contained in:
parent
bfda0b62da
commit
ea58b51619
@ -1,5 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import json
|
||||||
from typing import AsyncGenerator, Dict, Optional
|
from typing import AsyncGenerator, Dict, Optional
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
@ -42,17 +43,28 @@ class AlbyWallet(Wallet):
|
|||||||
async def status(self) -> StatusResponse:
|
async def status(self) -> StatusResponse:
|
||||||
try:
|
try:
|
||||||
r = await self.client.get("/balance", timeout=10)
|
r = await self.client.get("/balance", timeout=10)
|
||||||
except (httpx.ConnectError, httpx.RequestError):
|
r.raise_for_status()
|
||||||
return StatusResponse(f"Unable to connect to '{self.endpoint}'", 0)
|
|
||||||
|
|
||||||
if r.is_error:
|
|
||||||
error_message = r.json()["message"]
|
|
||||||
return StatusResponse(error_message, 0)
|
|
||||||
|
|
||||||
data = r.json()
|
data = r.json()
|
||||||
assert data["unit"] == "sat"
|
|
||||||
|
if len(data) == 0:
|
||||||
|
return StatusResponse("no data", 0)
|
||||||
|
|
||||||
|
if r.is_error or data["unit"] != "sat":
|
||||||
|
error_message = data["message"] if "message" in data else r.text
|
||||||
|
return StatusResponse(f"Server error: '{error_message}'", 0)
|
||||||
|
|
||||||
# multiply balance by 1000 to get msats balance
|
# multiply balance by 1000 to get msats balance
|
||||||
return StatusResponse(None, data["balance"] * 1000)
|
return StatusResponse(None, data["balance"] * 1000)
|
||||||
|
except KeyError as exc:
|
||||||
|
logger.warning(exc)
|
||||||
|
return StatusResponse("Server error: 'missing required fields'", 0)
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
logger.warning(exc)
|
||||||
|
return StatusResponse("Server error: 'invalid json response'", 0)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning(exc)
|
||||||
|
return StatusResponse(f"Unable to connect to {self.endpoint}.", 0)
|
||||||
|
|
||||||
async def create_invoice(
|
async def create_invoice(
|
||||||
self,
|
self,
|
||||||
@ -71,44 +83,83 @@ class AlbyWallet(Wallet):
|
|||||||
else:
|
else:
|
||||||
data["memo"] = memo or ""
|
data["memo"] = memo or ""
|
||||||
|
|
||||||
|
try:
|
||||||
r = await self.client.post(
|
r = await self.client.post(
|
||||||
"/invoices",
|
"/invoices",
|
||||||
json=data,
|
json=data,
|
||||||
timeout=40,
|
timeout=40,
|
||||||
)
|
)
|
||||||
|
r.raise_for_status()
|
||||||
if r.is_error:
|
|
||||||
error_message = r.json()["message"]
|
|
||||||
return InvoiceResponse(False, None, None, error_message)
|
|
||||||
|
|
||||||
data = r.json()
|
data = r.json()
|
||||||
|
|
||||||
|
if r.is_error:
|
||||||
|
error_message = data["message"] if "message" in data else r.text
|
||||||
|
return InvoiceResponse(False, None, None, error_message)
|
||||||
|
|
||||||
checking_id = data["payment_hash"]
|
checking_id = data["payment_hash"]
|
||||||
payment_request = data["payment_request"]
|
payment_request = data["payment_request"]
|
||||||
return InvoiceResponse(True, checking_id, payment_request, None)
|
return InvoiceResponse(True, checking_id, payment_request, None)
|
||||||
|
except KeyError as exc:
|
||||||
|
logger.warning(exc)
|
||||||
|
return InvoiceResponse(
|
||||||
|
False, None, None, "Server error: 'missing required fields'"
|
||||||
|
)
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
logger.warning(exc)
|
||||||
|
return InvoiceResponse(
|
||||||
|
False, None, None, "Server error: 'invalid json response'"
|
||||||
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning(exc)
|
||||||
|
return InvoiceResponse(
|
||||||
|
False, None, None, f"Unable to connect to {self.endpoint}."
|
||||||
|
)
|
||||||
|
|
||||||
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
|
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
|
||||||
|
try:
|
||||||
# https://api.getalby.com/payments/bolt11
|
# https://api.getalby.com/payments/bolt11
|
||||||
r = await self.client.post(
|
r = await self.client.post(
|
||||||
"/payments/bolt11",
|
"/payments/bolt11",
|
||||||
json={"invoice": bolt11}, # assume never need amount in body
|
json={"invoice": bolt11}, # assume never need amount in body
|
||||||
timeout=None,
|
timeout=None,
|
||||||
)
|
)
|
||||||
|
r.raise_for_status()
|
||||||
|
data = r.json()
|
||||||
|
|
||||||
if r.is_error:
|
if r.is_error:
|
||||||
error_message = r.json()["message"]
|
error_message = data["message"] if "message" in data else r.text
|
||||||
return PaymentResponse(False, None, None, None, error_message)
|
return PaymentResponse(False, None, None, None, error_message)
|
||||||
|
|
||||||
data = r.json()
|
|
||||||
checking_id = data["payment_hash"]
|
checking_id = data["payment_hash"]
|
||||||
|
# todo: confirm with bitkarrot that having the minus is fine
|
||||||
|
# other funding sources return a positive fee value
|
||||||
fee_msat = -data["fee"]
|
fee_msat = -data["fee"]
|
||||||
preimage = data["payment_preimage"]
|
preimage = data["payment_preimage"]
|
||||||
|
|
||||||
return PaymentResponse(True, checking_id, fee_msat, preimage, None)
|
return PaymentResponse(True, checking_id, fee_msat, preimage, None)
|
||||||
|
except KeyError as exc:
|
||||||
|
logger.warning(exc)
|
||||||
|
return PaymentResponse(
|
||||||
|
False, None, None, None, "Server error: 'missing required fields'"
|
||||||
|
)
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
logger.warning(exc)
|
||||||
|
return PaymentResponse(
|
||||||
|
False, None, None, None, "Server error: 'invalid json response'"
|
||||||
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.info(f"Failed to pay invoice {bolt11}")
|
||||||
|
logger.warning(exc)
|
||||||
|
return PaymentResponse(
|
||||||
|
False, None, None, None, f"Unable to connect to {self.endpoint}."
|
||||||
|
)
|
||||||
|
|
||||||
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||||
return await self.get_payment_status(checking_id)
|
return await self.get_payment_status(checking_id)
|
||||||
|
|
||||||
async def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
async def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||||
|
try:
|
||||||
r = await self.client.get(f"/invoices/{checking_id}")
|
r = await self.client.get(f"/invoices/{checking_id}")
|
||||||
|
|
||||||
if r.is_error:
|
if r.is_error:
|
||||||
@ -120,7 +171,16 @@ class AlbyWallet(Wallet):
|
|||||||
"CREATED": None,
|
"CREATED": None,
|
||||||
"SETTLED": True,
|
"SETTLED": True,
|
||||||
}
|
}
|
||||||
return PaymentStatus(statuses[data.get("state")], fee_msat=None, preimage=None)
|
# todo: extract fee and preimage
|
||||||
|
# maybe use the more specific endpoints:
|
||||||
|
# - https://api.getalby.com/invoices/incoming
|
||||||
|
# - https://api.getalby.com/invoices/outgoing
|
||||||
|
return PaymentStatus(
|
||||||
|
statuses[data.get("state")], fee_msat=None, preimage=None
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error getting invoice status: {e}")
|
||||||
|
return PaymentPendingStatus()
|
||||||
|
|
||||||
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
||||||
self.queue: asyncio.Queue = asyncio.Queue(0)
|
self.queue: asyncio.Queue = asyncio.Queue(0)
|
||||||
|
@ -89,10 +89,8 @@ class LndRestWallet(Wallet):
|
|||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
|
|
||||||
data = r.json()
|
data = r.json()
|
||||||
|
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
return StatusResponse("no data", 0)
|
return StatusResponse("no data", 0)
|
||||||
|
|
||||||
if r.is_error or "balance" not in data:
|
if r.is_error or "balance" not in data:
|
||||||
return StatusResponse(f"Server error: '{r.text}'", 0)
|
return StatusResponse(f"Server error: '{r.text}'", 0)
|
||||||
|
|
||||||
|
@ -209,7 +209,13 @@ def rest_wallet_fixtures_from_json(path) -> List["WalletTest"]:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
if "mocks" in test:
|
if "mocks" in test:
|
||||||
|
if fs_name not in test["mocks"]:
|
||||||
|
t.skip = True
|
||||||
|
tests[fs_name].append(t)
|
||||||
|
continue
|
||||||
|
|
||||||
test_mocks_names = test["mocks"][fs_name]
|
test_mocks_names = test["mocks"][fs_name]
|
||||||
|
|
||||||
fs_mocks = fn["mocks"][fs_name]
|
fs_mocks = fn["mocks"][fs_name]
|
||||||
for mock_name in fs_mocks:
|
for mock_name in fs_mocks:
|
||||||
for test_mock in test_mocks_names[mock_name]:
|
for test_mock in test_mocks_names[mock_name]:
|
||||||
@ -223,6 +229,7 @@ def rest_wallet_fixtures_from_json(path) -> List["WalletTest"]:
|
|||||||
f"""{t.description}:{mock.description or ""}"""
|
f"""{t.description}:{mock.description or ""}"""
|
||||||
)
|
)
|
||||||
unique_test.mocks = t.mocks + [mock]
|
unique_test.mocks = t.mocks + [mock]
|
||||||
|
unique_test.skip = mock.skip
|
||||||
|
|
||||||
tests[fs_name].append(unique_test)
|
tests[fs_name].append(unique_test)
|
||||||
else:
|
else:
|
||||||
@ -246,6 +253,7 @@ class FunctionMock(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class TestMock(BaseModel):
|
class TestMock(BaseModel):
|
||||||
|
skip: Optional[bool]
|
||||||
description: Optional[str]
|
description: Optional[str]
|
||||||
request_type: Optional[str]
|
request_type: Optional[str]
|
||||||
request_body: Optional[dict]
|
request_body: Optional[dict]
|
||||||
@ -279,6 +287,7 @@ class FunctionData(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class WalletTest(BaseModel):
|
class WalletTest(BaseModel):
|
||||||
|
skip: Optional[bool]
|
||||||
function: str
|
function: str
|
||||||
description: str
|
description: str
|
||||||
funding_source: FundingSourceConfig
|
funding_source: FundingSourceConfig
|
||||||
|
@ -14,6 +14,13 @@
|
|||||||
"lnd_rest_macaroon": "eNcRyPtEdMaCaRoOn",
|
"lnd_rest_macaroon": "eNcRyPtEdMaCaRoOn",
|
||||||
"lnd_rest_cert": ""
|
"lnd_rest_cert": ""
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"wallet_class": "AlbyWallet",
|
||||||
|
"settings": {
|
||||||
|
"alby_api_endpoint": "http://127.0.0.1:8555",
|
||||||
|
"alby_access_token": "mock-alby-access-token"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"functions": {
|
"functions": {
|
||||||
@ -40,6 +47,16 @@
|
|||||||
},
|
},
|
||||||
"method": "GET"
|
"method": "GET"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"status_endpoint": {
|
||||||
|
"uri": "/balance",
|
||||||
|
"headers": {
|
||||||
|
"Authorization": "Bearer mock-alby-access-token",
|
||||||
|
"User-Agent": "LNbits/Tests"
|
||||||
|
},
|
||||||
|
"method": "GET"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tests": [
|
"tests": [
|
||||||
@ -70,6 +87,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"status_endpoint": [
|
||||||
|
{
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {
|
||||||
|
"balance": 55,
|
||||||
|
"unit": "sat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -98,6 +126,17 @@
|
|||||||
"response": "test-error"
|
"response": "test-error"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"status_endpoint": [
|
||||||
|
{
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {
|
||||||
|
"message": "\"test-error\"",
|
||||||
|
"unit": "sats"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -124,6 +163,14 @@
|
|||||||
"response": {}
|
"response": {}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"status_endpoint": [
|
||||||
|
{
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -150,6 +197,14 @@
|
|||||||
"response": "data-not-json"
|
"response": "data-not-json"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"status_endpoint": [
|
||||||
|
{
|
||||||
|
"response_type": "data",
|
||||||
|
"response": "data-not-json"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -182,6 +237,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"status_endpoint": [
|
||||||
|
{
|
||||||
|
"response_type": "response",
|
||||||
|
"response": {
|
||||||
|
"response": "Not Found",
|
||||||
|
"status": 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -218,6 +284,16 @@
|
|||||||
},
|
},
|
||||||
"method": "POST"
|
"method": "POST"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"create_invoice_endpoint": {
|
||||||
|
"uri": "/invoices",
|
||||||
|
"headers": {
|
||||||
|
"Authorization": "Bearer mock-alby-access-token",
|
||||||
|
"User-Agent": "LNbits/Tests"
|
||||||
|
},
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tests": [
|
"tests": [
|
||||||
@ -268,6 +344,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"create_invoice_endpoint": [
|
||||||
|
{
|
||||||
|
"request_type": "json",
|
||||||
|
"request_body": {
|
||||||
|
"value": 555,
|
||||||
|
"memo": "Test Invoice"
|
||||||
|
},
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {
|
||||||
|
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||||
|
"payment_request": "lnbc5550n1pnq9jg3sp52rvwstvjcypjsaenzdh0h30jazvzsf8aaye0julprtth9kysxtuspp5e5s3z7felv4t9zrcc6wpn7ehvjl5yzewanzl5crljdl3jgeffyhqdq2f38xy6t5wvxqzjccqpjrzjq0yzeq76ney45hmjlnlpvu0nakzy2g35hqh0dujq8ujdpr2e42pf2rrs6vqpgcsqqqqqqqqqqqqqqeqqyg9qxpqysgqwftcx89k5pp28435pgxfl2vx3ksemzxccppw2j9yjn0ngr6ed7wj8ztc0d5kmt2mvzdlcgrludhz7jncd5l5l9w820hc4clpwhtqj3gq62g66n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -316,6 +408,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"create_invoice_endpoint": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -364,6 +459,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"create_invoice_endpoint": [
|
||||||
|
{
|
||||||
|
"description": "missing payment request",
|
||||||
|
"request_type": "json",
|
||||||
|
"request_body": {
|
||||||
|
"value": 555,
|
||||||
|
"memo": "Test Invoice"
|
||||||
|
},
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {
|
||||||
|
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -408,6 +519,19 @@
|
|||||||
"response": "data-not-json"
|
"response": "data-not-json"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"create_invoice_endpoint": [
|
||||||
|
{
|
||||||
|
"request_type": "json",
|
||||||
|
"request_body": {
|
||||||
|
"value": 555,
|
||||||
|
"memo": "Test Invoice"
|
||||||
|
},
|
||||||
|
"response_type": "data",
|
||||||
|
"response": "data-not-json"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -458,6 +582,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"create_invoice_endpoint": [
|
||||||
|
{
|
||||||
|
"request_type": "json",
|
||||||
|
"request_body": {
|
||||||
|
"value": 555,
|
||||||
|
"memo": "Test Invoice"
|
||||||
|
},
|
||||||
|
"response_type": "response",
|
||||||
|
"response": {
|
||||||
|
"response": "Not Found",
|
||||||
|
"status": 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -500,6 +640,16 @@
|
|||||||
},
|
},
|
||||||
"method": "POST"
|
"method": "POST"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"pay_invoice_endpoint": {
|
||||||
|
"uri": "/payments/bolt11",
|
||||||
|
"headers": {
|
||||||
|
"Authorization": "Bearer mock-alby-access-token",
|
||||||
|
"User-Agent": "LNbits/Tests"
|
||||||
|
},
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tests": [
|
"tests": [
|
||||||
@ -555,6 +705,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"pay_invoice_endpoint": [
|
||||||
|
{
|
||||||
|
"skip": true,
|
||||||
|
"request_type": "json",
|
||||||
|
"request_body": {
|
||||||
|
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||||
|
},
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {
|
||||||
|
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||||
|
"fee": 50,
|
||||||
|
"payment_preimage": "0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -602,6 +769,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"pay_invoice_endpoint": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -645,6 +815,18 @@
|
|||||||
"response": {}
|
"response": {}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"pay_invoice_endpoint": [
|
||||||
|
{
|
||||||
|
"request_type": "json",
|
||||||
|
"request_body": {
|
||||||
|
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||||
|
},
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -688,6 +870,18 @@
|
|||||||
"response": "data-not-json"
|
"response": "data-not-json"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"pay_invoice_endpoint": [
|
||||||
|
{
|
||||||
|
"request_type": "json",
|
||||||
|
"request_body": {
|
||||||
|
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||||
|
},
|
||||||
|
"response_type": "data",
|
||||||
|
"response": "data-not-json"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -737,6 +931,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"pay_invoice_endpoint": [
|
||||||
|
{
|
||||||
|
"request_type": "json",
|
||||||
|
"request_body": {
|
||||||
|
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||||
|
},
|
||||||
|
"response_type": "response",
|
||||||
|
"response": {
|
||||||
|
"response": "Not Found",
|
||||||
|
"status": 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -782,6 +991,16 @@
|
|||||||
},
|
},
|
||||||
"method": "GET"
|
"method": "GET"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"get_invoice_status_endpoint": {
|
||||||
|
"uri": "/invoices/e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||||
|
"headers": {
|
||||||
|
"Authorization": "Bearer mock-alby-access-token",
|
||||||
|
"User-Agent": "LNbits/Tests"
|
||||||
|
},
|
||||||
|
"method": "GET"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tests": [
|
"tests": [
|
||||||
@ -829,6 +1048,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"get_invoice_status_endpoint": [
|
||||||
|
{
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {
|
||||||
|
"state": "SETTLED"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -861,6 +1090,10 @@
|
|||||||
"lndrest": {
|
"lndrest": {
|
||||||
"description": "lndrest.py doesn't handle the 'failed' status for `get_invoice_status`",
|
"description": "lndrest.py doesn't handle the 'failed' status for `get_invoice_status`",
|
||||||
"get_invoice_status_endpoint": []
|
"get_invoice_status_endpoint": []
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"description": "alby.py doesn't handle the 'failed' status for `get_invoice_status`",
|
||||||
|
"get_invoice_status_endpoint": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -932,6 +1165,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"get_invoice_status_endpoint": [
|
||||||
|
{
|
||||||
|
"description": "error status",
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "error status",
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {
|
||||||
|
"status": "CREATED"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "bad json",
|
||||||
|
"response_type": "data",
|
||||||
|
"response": "data-not-json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "http 404",
|
||||||
|
"response_type": "response",
|
||||||
|
"response": {
|
||||||
|
"response": "Not Found",
|
||||||
|
"status": 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -974,6 +1236,16 @@
|
|||||||
},
|
},
|
||||||
"method": "GET"
|
"method": "GET"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"get_payment_status_endpoint": {
|
||||||
|
"uri": "/invoices/e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||||
|
"headers": {
|
||||||
|
"Authorization": "Bearer mock-alby-access-token",
|
||||||
|
"User-Agent": "LNbits/Tests"
|
||||||
|
},
|
||||||
|
"method": "GET"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tests": [
|
"tests": [
|
||||||
@ -1019,6 +1291,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"get_payment_status_endpoint": [
|
||||||
|
{
|
||||||
|
"skip": true,
|
||||||
|
"response_type": "json",
|
||||||
|
"response": {
|
||||||
|
"result": {
|
||||||
|
"status": "SETTLED"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1070,6 +1355,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"get_payment_status_endpoint": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1174,6 +1462,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"alby": {
|
||||||
|
"get_payment_status_endpoint": [
|
||||||
|
{
|
||||||
|
"description": "CREATED",
|
||||||
|
"response_type": "stream",
|
||||||
|
"response": {
|
||||||
|
"result": {
|
||||||
|
"state": "CREATED"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "no data",
|
||||||
|
"response_type": "stream",
|
||||||
|
"response": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "bad json",
|
||||||
|
"response_type": "stream",
|
||||||
|
"response": "data-not-json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "http 404",
|
||||||
|
"response_type": "response",
|
||||||
|
"response": {
|
||||||
|
"response": "Not Found",
|
||||||
|
"status": 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -40,6 +40,9 @@ def build_test_id(test: WalletTest):
|
|||||||
ids=build_test_id,
|
ids=build_test_id,
|
||||||
)
|
)
|
||||||
async def test_rest_wallet(httpserver: HTTPServer, test_data: WalletTest):
|
async def test_rest_wallet(httpserver: HTTPServer, test_data: WalletTest):
|
||||||
|
if test_data.skip:
|
||||||
|
pytest.skip()
|
||||||
|
|
||||||
for mock in test_data.mocks:
|
for mock in test_data.mocks:
|
||||||
_apply_mock(httpserver, mock)
|
_apply_mock(httpserver, mock)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user