Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

from_xrpl should not accept snake_case dict keys #694

Merged
merged 18 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [[Unreleased]]
- Included `ctid` field in the `tx` request.
- `from_xrpl` method accepts input dictionary keys exclusively in the proper XRPL format.

### Fixed
- Added support for `XChainModifyBridge` flag maps (fixing an issue with `NFTokenCreateOffer` flag names)
Expand Down
42 changes: 42 additions & 0 deletions tests/unit/models/test_base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,48 @@ def test_from_dict_submit(self):
actual = Request.from_dict(request)
self.assertEqual(actual, expected)

# Note: BaseModel.from_xrpl and its overridden methods accept only camelCase or
# PascalCase inputs (i.e. snake_case is not accepted)
def test_from_xrpl_accepts_only_camel_case_inputs(self):
request = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between this test case and tx_snake_case_keys? Just want to make sure I'm following what's going on here :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, both the tests dis-allow snake_case keys in Request and Transaction models, respectively. I used different inputs for two different models

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you split it into 2 tests (2 functions)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 58ff257

"method": "submit",
"tx_json": {
"Account": "rnD6t3JF9RTG4VgNLoc4i44bsQLgJUSi6h",
"transaction_type": "TrustSet",
"Fee": "10",
"Sequence": 17896798,
"Flags": 131072,
"signing_pub_key": "",
"limit_amount": {
"currency": "USD",
"issuer": "rH5gvkKxGHrFAMAACeu9CB3FMu7pQ9jfZm",
"value": "10",
},
},
"fail_hard": False,
}

with self.assertRaises(XRPLModelException):
Request.from_xrpl(request)

# verify that Transaction.from_xrpl method does not accept snake_case JSON keys
tx_snake_case_keys = {
"Account": "rnoGkgSpt6AX1nQxZ2qVGx7Fgw6JEcoQas",
"transaction_type": "TrustSet",
"Fee": "10",
"Sequence": 17892983,
"Flags": 131072,
"signing_pub_key": "",
"limit_amount": {
"currency": "USD",
"issuer": "rBPvTKisx7UCGLDtiUZ6mDssXNREuVuL8Y",
"value": "10",
},
}

with self.assertRaises(XRPLModelException):
Transaction.from_xrpl(tx_snake_case_keys)

def test_from_xrpl(self):
dirname = os.path.dirname(__file__)
full_filename = "x-codec-fixtures.json"
Expand Down
9 changes: 9 additions & 0 deletions xrpl/models/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from xrpl.models.required import REQUIRED
from xrpl.models.types import XRPL_VALUE_TYPE

_PASCAL_OR_CAMEL_CASE: Final[Pattern[str]] = re.compile("^[A-Za-z]+(?:[A-Z][a-z]+)*$")
# this regex splits words based on one of three cases:
#
# 1. 1-or-more non-capital chars at the beginning of the string. Handles cases
Expand Down Expand Up @@ -54,7 +55,15 @@ def _key_to_json(field: str) -> str:
1. 'TransactionType' becomes 'transaction_type'
2. 'value' remains 'value'
3. 'URI' becomes 'uri'

This function accepts inputs in PascalCase or camelCase only

Raises:
XRPLModelException: If the input is invalid
"""
if not re.fullmatch(pattern=_PASCAL_OR_CAMEL_CASE, string=field):
raise XRPLModelException(f"Key {field} is not in the proper XRPL format.")

# convert all special CamelCase substrings to capitalized strings
for spec_str in ABBREVIATIONS.values():
if spec_str in field:
Expand Down
Loading