nucypher/tests/unit/conditions/test_condition_lingo.py

134 lines
4.1 KiB
Python
Raw Normal View History

import json
import pytest
from packaging.version import parse as parse_version
import nucypher
from nucypher.blockchain.eth.constants import NULL_ADDRESS
from nucypher.policy.conditions.context import USER_ADDRESS_CONTEXT
from nucypher.policy.conditions.exceptions import InvalidConditionLingo
2022-09-22 11:42:48 +00:00
from nucypher.policy.conditions.lingo import ConditionLingo
from tests.constants import TESTERCHAIN_CHAIN_ID
2022-09-22 11:42:48 +00:00
2022-11-17 11:20:53 +00:00
@pytest.fixture(scope='module')
def lingo():
return {
"version": ConditionLingo.VERSION,
"condition": {
"operator": "and",
"operands": [
{
"returnValueTest": {"value": 0, "comparator": ">"},
"method": "blocktime",
"chain": TESTERCHAIN_CHAIN_ID,
},
{
"returnValueTest": {"value": 99999999999999999, "comparator": "<"},
"method": "blocktime",
"chain": TESTERCHAIN_CHAIN_ID,
},
],
},
}
2022-09-22 11:42:48 +00:00
2022-11-10 14:16:36 +00:00
def test_invalid_condition(lingo):
# no version or condition
with pytest.raises(InvalidConditionLingo):
ConditionLingo.from_dict({})
# no condition
with pytest.raises(InvalidConditionLingo):
ConditionLingo.from_dict({"version": ConditionLingo.VERSION})
# invalid condition
with pytest.raises(InvalidConditionLingo):
ConditionLingo.from_dict(
{
"version": ConditionLingo.VERSION,
"condition": {"dont_mind_me": "nothing_to_see_here"},
}
)
# < 2 operands for and condition
invalid_operator_position_lingo = {
"version": ConditionLingo.VERSION,
"condition": {
"operator": "and",
"operands": [
{
"returnValueTest": {"value": 0, "comparator": ">"},
"method": "blocktime",
"chain": TESTERCHAIN_CHAIN_ID,
}
],
},
}
with pytest.raises(InvalidConditionLingo):
ConditionLingo.from_dict(invalid_operator_position_lingo)
@pytest.mark.parametrize("case", ["major", "minor", "patch"])
def test_invalid_condition_version(case):
# version in the future
current_version = parse_version(ConditionLingo.VERSION)
major = current_version.major
minor = current_version.minor
patch = current_version.micro
if case == "major":
major += 1
elif case == "minor":
minor += 1
else:
patch += 1
newer_version_string = f"{major}.{minor}.{patch}"
lingo_dict = {
"version": newer_version_string,
"condition": {
"returnValueTest": {"value": 0, "comparator": ">"},
"method": "blocktime",
"chain": TESTERCHAIN_CHAIN_ID,
},
}
if case == "major":
# exception should be thrown since incompatible:
with pytest.raises(InvalidConditionLingo):
ConditionLingo.from_dict(lingo_dict)
else:
# no exception thrown
ConditionLingo.from_dict(lingo_dict)
def test_condition_lingo_to_from_dict(lingo):
clingo = ConditionLingo.from_dict(lingo)
clingo_dict = clingo.to_dict()
assert clingo_dict == lingo
2022-11-10 14:16:36 +00:00
2022-11-17 11:20:53 +00:00
def test_condition_lingo_repr(lingo):
clingo = ConditionLingo.from_dict(lingo)
2022-11-10 14:16:36 +00:00
clingo_string = f"{clingo}"
assert f"{clingo.__class__.__name__}" in clingo_string
assert f"version={ConditionLingo.VERSION}" in clingo_string
2022-11-10 14:16:36 +00:00
assert f"id={clingo.id}" in clingo_string
assert f"size={len(bytes(clingo))}" in clingo_string
2022-11-17 15:27:24 +00:00
def test_lingo_parameter_int_type_preservation(custom_abi_with_multiple_parameters, mocker):
mocker.patch.dict(
nucypher.policy.conditions.context._DIRECTIVES,
{USER_ADDRESS_CONTEXT: lambda: NULL_ADDRESS},
)
clingo = ConditionLingo.from_dict(
{
"version": ConditionLingo.VERSION,
"condition": json.loads(
custom_abi_with_multiple_parameters
), # TODO fix this
}
)
conditions = clingo.to_dict()
assert conditions["condition"]["parameters"][2] == 4