mirror of
https://github.com/lnbits/lnbits.git
synced 2025-07-28 13:42:42 +02:00
test: add unit tests for wallets (funding sources) (#2363)
* test: initial commit * feat: allow external label for `create_invoice` (useful for testing) * chore: code format * fix: ignore temp coverage files * feat: add properties to the Status classes for a better readability * fix: add extra validation for data * fix: comment out bad `status.pending` (to be fixed in core) * fix: 404 tests * test: first draft of generic rest wallet tests * test: migrate two more tests * feat: add response type * feat: test exceptions * test: extract first `create_invoice` test * chore: reminder * add: error test * chore: code format * chore: experiment * feat: adapt parsing * refactor: data structure * fix: some tests * refactor: extract methods * 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 * fix: response type * 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 * fix: error handling * 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: extract `rest_wallet_fixtures_from_json` function * chore: update comment * feat: cover `cleanup` call also * chore: code format * refactor: start to extract data model * refactor: extract mock class * fix: typings * refactor: improve typings * chore: add some documentation * chore: final clean-up * chore: rename file * chore: `poetry add --dev pytest_httpserver` (after rebase)
This commit is contained in:
110
tests/helpers.py
110
tests/helpers.py
@@ -5,11 +5,12 @@ import random
|
||||
import string
|
||||
import time
|
||||
from subprocess import PIPE, Popen, TimeoutExpired
|
||||
from typing import Optional, Tuple
|
||||
from typing import Dict, List, Optional, Tuple, Union
|
||||
|
||||
from loguru import logger
|
||||
from psycopg2 import connect
|
||||
from psycopg2.errors import InvalidCatalogName
|
||||
from pydantic import BaseModel
|
||||
|
||||
from lnbits import core
|
||||
from lnbits.db import DB_TYPE, POSTGRES, FromRowModel
|
||||
@@ -178,3 +179,110 @@ def clean_database(settings):
|
||||
# TODO: do this once mock data is removed from test data folder
|
||||
# os.remove(settings.lnbits_data_folder + "/database.sqlite3")
|
||||
pass
|
||||
|
||||
|
||||
def rest_wallet_fixtures_from_json(path) -> List["WalletTest"]:
|
||||
with open(path) as f:
|
||||
data = json.load(f)
|
||||
|
||||
funding_sources = data["funding_sources"]
|
||||
|
||||
tests: Dict[str, List[WalletTest]] = {
|
||||
fs_name: [] for fs_name in funding_sources
|
||||
}
|
||||
|
||||
for fn_name in data["functions"]:
|
||||
fn = data["functions"][fn_name]
|
||||
|
||||
for test in fn["tests"]:
|
||||
"""create an unit test for each funding source"""
|
||||
|
||||
for fs_name in funding_sources:
|
||||
t = WalletTest(
|
||||
**{
|
||||
"funding_source": FundingSourceConfig(
|
||||
**funding_sources[fs_name]
|
||||
),
|
||||
"function": fn_name,
|
||||
**test,
|
||||
"mocks": [],
|
||||
}
|
||||
)
|
||||
if "mocks" in test:
|
||||
test_mocks_names = test["mocks"][fs_name]
|
||||
fs_mocks = fn["mocks"][fs_name]
|
||||
for mock_name in fs_mocks:
|
||||
for test_mock in test_mocks_names[mock_name]:
|
||||
# different mocks that result in the same
|
||||
# return value for the tested function
|
||||
_mock = fs_mocks[mock_name] | test_mock
|
||||
mock = Mock(**_mock)
|
||||
|
||||
unique_test = WalletTest(**t.dict())
|
||||
unique_test.description = (
|
||||
f"""{t.description}:{mock.description or ""}"""
|
||||
)
|
||||
unique_test.mocks = t.mocks + [mock]
|
||||
|
||||
tests[fs_name].append(unique_test)
|
||||
else:
|
||||
# add the test without mocks
|
||||
tests[fs_name].append(t)
|
||||
|
||||
all_tests = sum([tests[fs_name] for fs_name in tests], [])
|
||||
return all_tests
|
||||
|
||||
|
||||
class FundingSourceConfig(BaseModel):
|
||||
wallet_class: str
|
||||
settings: dict
|
||||
|
||||
|
||||
class FunctionMock(BaseModel):
|
||||
uri: str
|
||||
query_params: Optional[dict]
|
||||
headers: dict
|
||||
method: str
|
||||
|
||||
|
||||
class TestMock(BaseModel):
|
||||
description: Optional[str]
|
||||
request_type: Optional[str]
|
||||
request_body: Optional[dict]
|
||||
response_type: str
|
||||
response: Union[str, dict]
|
||||
|
||||
|
||||
class Mock(FunctionMock, TestMock):
|
||||
pass
|
||||
|
||||
|
||||
class FunctionMocks(BaseModel):
|
||||
mocks: Dict[str, FunctionMock]
|
||||
|
||||
|
||||
class FunctionTest(BaseModel):
|
||||
description: str
|
||||
call_params: dict
|
||||
expect: dict
|
||||
mocks: Dict[str, List[Dict[str, TestMock]]]
|
||||
|
||||
|
||||
class FunctionData(BaseModel):
|
||||
"""Data required for testing this function"""
|
||||
|
||||
"Function level mocks that apply for all tests of this function"
|
||||
mocks: List[FunctionMock] = []
|
||||
|
||||
"All the tests for this function"
|
||||
tests: List[FunctionTest] = []
|
||||
|
||||
|
||||
class WalletTest(BaseModel):
|
||||
function: str
|
||||
description: str
|
||||
funding_source: FundingSourceConfig
|
||||
call_params: Optional[dict] = {}
|
||||
expect: Optional[dict]
|
||||
expect_error: Optional[dict]
|
||||
mocks: List[Mock] = []
|
||||
|
Reference in New Issue
Block a user