[test] create unit-test framework for RPC wallets (#2396)
---------
Co-authored-by: dni ⚡ <office@dnilabs.com>
This commit is contained in:
parent
b145bff566
commit
69ce0e565b
13 changed files with 2128 additions and 270 deletions
117
tests/wallets/helpers.py
Normal file
117
tests/wallets/helpers.py
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
import importlib
|
||||
import json
|
||||
from typing import Dict, List
|
||||
|
||||
import pytest
|
||||
|
||||
from lnbits.core.models import BaseWallet
|
||||
from tests.wallets.fixtures.models import FundingSourceConfig, WalletTest
|
||||
|
||||
wallets_module = importlib.import_module("lnbits.wallets")
|
||||
|
||||
|
||||
def wallet_fixtures_from_json(path) -> List["WalletTest"]:
|
||||
with open(path) as f:
|
||||
data = json.load(f)
|
||||
|
||||
funding_sources = [
|
||||
FundingSourceConfig(name=fs_name, **data["funding_sources"][fs_name])
|
||||
for fs_name in data["funding_sources"]
|
||||
]
|
||||
tests: Dict[str, List[WalletTest]] = {}
|
||||
for fn_name in data["functions"]:
|
||||
fn = data["functions"][fn_name]
|
||||
fn_tests = _tests_for_function(funding_sources, fn_name, fn)
|
||||
_merge_dict_of_lists(tests, fn_tests)
|
||||
|
||||
all_tests = sum([tests[fs_name] for fs_name in tests], [])
|
||||
return all_tests
|
||||
|
||||
|
||||
def _tests_for_function(
|
||||
funding_sources: List[FundingSourceConfig], fn_name: str, fn
|
||||
) -> Dict[str, List[WalletTest]]:
|
||||
tests: Dict[str, List[WalletTest]] = {}
|
||||
for test in fn["tests"]:
|
||||
"""create an unit test for each funding source"""
|
||||
|
||||
fs_tests = _tests_for_funding_source(funding_sources, fn_name, fn, test)
|
||||
_merge_dict_of_lists(tests, fs_tests)
|
||||
|
||||
return tests
|
||||
|
||||
|
||||
def _tests_for_funding_source(
|
||||
funding_sources: List[FundingSourceConfig], fn_name: str, fn, test
|
||||
) -> Dict[str, List[WalletTest]]:
|
||||
tests: Dict[str, List[WalletTest]] = {fs.name: [] for fs in funding_sources}
|
||||
for fs in funding_sources:
|
||||
tests[fs.name] += WalletTest.tests_for_funding_source(fs, fn_name, fn, test)
|
||||
return tests
|
||||
|
||||
|
||||
def build_test_id(test: WalletTest):
|
||||
return f"{test.funding_source}.{test.function}({test.description})"
|
||||
|
||||
|
||||
def load_funding_source(funding_source: FundingSourceConfig) -> BaseWallet:
|
||||
custom_settings = funding_source.settings
|
||||
original_settings = {}
|
||||
|
||||
settings = getattr(wallets_module, "settings")
|
||||
|
||||
for s in custom_settings:
|
||||
original_settings[s] = getattr(settings, s)
|
||||
setattr(settings, s, custom_settings[s])
|
||||
|
||||
fs_instance: BaseWallet = getattr(wallets_module, funding_source.wallet_class)()
|
||||
|
||||
# rollback settings (global variable)
|
||||
for s in original_settings:
|
||||
setattr(settings, s, original_settings[s])
|
||||
|
||||
return fs_instance
|
||||
|
||||
|
||||
async def check_assertions(wallet, _test_data: WalletTest):
|
||||
test_data = _test_data.dict()
|
||||
tested_func = _test_data.function
|
||||
call_params = _test_data.call_params
|
||||
|
||||
if "expect" in test_data:
|
||||
await _assert_data(wallet, tested_func, call_params, _test_data.expect)
|
||||
# if len(_test_data.mocks) == 0:
|
||||
# # all calls should fail after this method is called
|
||||
# await wallet.cleanup()
|
||||
# # same behaviour expected is server canot be reached
|
||||
# # or if the connection was closed
|
||||
# await _assert_data(wallet, tested_func, call_params, _test_data.expect)
|
||||
elif "expect_error" in test_data:
|
||||
await _assert_error(wallet, tested_func, call_params, _test_data.expect_error)
|
||||
else:
|
||||
assert False, "Expected outcome not specified"
|
||||
|
||||
|
||||
async def _assert_data(wallet, tested_func, call_params, expect):
|
||||
resp = await getattr(wallet, tested_func)(**call_params)
|
||||
for key in expect:
|
||||
received = getattr(resp, key)
|
||||
expected = expect[key]
|
||||
assert (
|
||||
getattr(resp, key) == expect[key]
|
||||
), f"""Field "{key}". Received: "{received}". Expected: "{expected}"."""
|
||||
|
||||
|
||||
async def _assert_error(wallet, tested_func, call_params, expect_error):
|
||||
error_module = importlib.import_module(expect_error["module"])
|
||||
error_class = getattr(error_module, expect_error["class"])
|
||||
with pytest.raises(error_class) as e_info:
|
||||
await getattr(wallet, tested_func)(**call_params)
|
||||
|
||||
assert e_info.match(expect_error["message"])
|
||||
|
||||
|
||||
def _merge_dict_of_lists(v1: Dict[str, List], v2: Dict[str, List]):
|
||||
"""Merge v2 into v1"""
|
||||
for k in v2:
|
||||
v1[k] = v2[k] if k not in v1 else v1[k] + v2[k]
|
||||
Loading…
Add table
Add a link
Reference in a new issue