From 3ab3df568fd276542c1a84ed5395174c07c812bf Mon Sep 17 00:00:00 2001 From: YoshihitoAso Date: Fri, 22 Dec 2023 18:27:51 +0900 Subject: [PATCH] Fix upper limit check when uploading external data --- app/model/schema/ledger.py | 5 +- cmd/explorer/src/connector/__init__.py | 1 - ...edger_{token_address}_details_data_POST.py | 138 +++++++++++----- ...en_address}_details_data_{data_id}_POST.py | 152 +++++++++++++----- 4 files changed, 211 insertions(+), 85 deletions(-) diff --git a/app/model/schema/ledger.py b/app/model/schema/ledger.py index e8588706..fa95d2d1 100644 --- a/app/model/schema/ledger.py +++ b/app/model/schema/ledger.py @@ -16,6 +16,7 @@ SPDX-License-Identifier: Apache-2.0 """ +import sys from datetime import datetime from typing import List, Optional @@ -67,8 +68,8 @@ class CreateUpdateLedgerDetailsDataRequest(BaseModel): name: Optional[str] = Field(None, max_length=200) address: Optional[str] = Field(None, max_length=200) amount: Optional[int] = Field(None, ge=0, le=1_000_000_000_000) - price: Optional[int] = Field(None, ge=0, le=5_000_000_000) - balance: Optional[int] = Field(None, ge=0, le=1_000_000_000_000 * 5_000_000_000) + price: Optional[int] = Field(None, ge=0, le=1_000_000_000_000) + balance: Optional[int] = Field(None, ge=0, le=sys.maxsize) acquisition_date: Optional[str] = Field( None, min_length=10, max_length=10, description="YYYY/MM/DD" ) diff --git a/cmd/explorer/src/connector/__init__.py b/cmd/explorer/src/connector/__init__.py index 34464b59..6f06648c 100644 --- a/cmd/explorer/src/connector/__init__.py +++ b/cmd/explorer/src/connector/__init__.py @@ -22,7 +22,6 @@ from typing import Any from aiohttp import ClientSession - from cache import AsyncTTL path = os.path.join(os.path.dirname(__file__), "../../../../") diff --git a/tests/test_app_routers_ledger_{token_address}_details_data_POST.py b/tests/test_app_routers_ledger_{token_address}_details_data_POST.py index 182cf6b2..97888152 100644 --- a/tests/test_app_routers_ledger_{token_address}_details_data_POST.py +++ b/tests/test_app_routers_ledger_{token_address}_details_data_POST.py @@ -16,6 +16,8 @@ SPDX-License-Identifier: Apache-2.0 """ +import sys + from sqlalchemy import select from app.model.db import LedgerDetailsData, Token, TokenType, TokenVersion @@ -99,6 +101,61 @@ def test_normal_1(self, client, db): assert _details_data.balance == 200 assert _details_data.acquisition_date == "2020/01/02" + # + # Max value + def test_normal_2(self, client, db): + user = config_eth_account("user1") + issuer_address = user["address"] + token_address = "0xABCdeF1234567890abcdEf123456789000000000" + + # prepare data + _token = Token() + _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.tx_hash = "" + _token.issuer_address = issuer_address + _token.token_address = token_address + _token.abi = {} + _token.version = TokenVersion.V_23_12 + db.add(_token) + + # request target API + req_param = [ + { + "name": "name_test_1", + "address": "address_test_1", + "amount": 1_000_000_000_000, + "price": 1_000_000_000_000, + "balance": sys.maxsize, + "acquisition_date": "2020/01/01", + }, + ] + resp = client.post( + self.base_url.format(token_address=token_address), + json=req_param, + headers={ + "issuer-address": issuer_address, + }, + ) + + # assertion + assert resp.status_code == 200 + assert resp.json()["data_id"] is not None + + _details_data_list = db.scalars( + select(LedgerDetailsData).order_by(LedgerDetailsData.id) + ).all() + assert len(_details_data_list) == 1 + + _details_data = _details_data_list[0] + assert _details_data.id == 1 + assert _details_data.data_id == resp.json()["data_id"] + assert _details_data.name == "name_test_1" + assert _details_data.address == "address_test_1" + assert _details_data.amount == 1_000_000_000_000 + assert _details_data.price == 1_000_000_000_000 + assert _details_data.balance == sys.maxsize + assert _details_data.acquisition_date == "2020/01/01" + ########################################################################### # Error Case ########################################################################### @@ -193,9 +250,9 @@ def test_error_3(self, client, db): "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" "1", "address": "address_test_1", - "amount": 1_000_000_000_001, + "amount": -1, "price": -1, - "balance": 1_000_000_000_001 * 5_000_000_001, + "balance": -1, "acquisition_date": "2020/01/01a", }, { @@ -203,9 +260,9 @@ def test_error_3(self, client, db): "address": "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" "1", - "amount": -1, - "price": 5_000_000_001, - "balance": -1, + "amount": 1_000_000_000_001, + "price": 1_000_000_000_001, + "balance": sys.maxsize + 1, "acquisition_date": "2020/02/31", }, ] @@ -223,75 +280,74 @@ def test_error_3(self, client, db): "meta": {"code": 1, "title": "RequestValidationError"}, "detail": [ { - "ctx": {"max_length": 200}, - "input": "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", + "type": "string_too_long", "loc": ["body", 0, "name"], "msg": "String should have at most 200 characters", - "type": "string_too_long", + "input": "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", + "ctx": {"max_length": 200}, }, { - "ctx": {"le": 1000000000000}, - "input": 1000000000001, + "type": "greater_than_equal", "loc": ["body", 0, "amount"], - "msg": "Input should be less than or equal to 1000000000000", - "type": "less_than_equal", + "msg": "Input should be greater than or equal to 0", + "input": -1, + "ctx": {"ge": 0}, }, { - "ctx": {"ge": 0}, - "input": -1, + "type": "greater_than_equal", "loc": ["body", 0, "price"], "msg": "Input should be greater than or equal to 0", - "type": "greater_than_equal", + "input": -1, + "ctx": {"ge": 0}, }, { - "ctx": {"le": 5000000000000000000000}, - "input": 5000000001005000000001, + "type": "greater_than_equal", "loc": ["body", 0, "balance"], - "msg": "Input should be less than or equal to " - "5000000000000000000000", - "type": "less_than_equal", + "msg": "Input should be greater than or equal to 0", + "input": -1, + "ctx": {"ge": 0}, }, { - "ctx": {"max_length": 10}, - "input": "2020/01/01a", + "type": "string_too_long", "loc": ["body", 0, "acquisition_date"], "msg": "String should have at most 10 characters", - "type": "string_too_long", + "input": "2020/01/01a", + "ctx": {"max_length": 10}, }, { - "ctx": {"max_length": 200}, - "input": "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", + "type": "string_too_long", "loc": ["body", 1, "address"], "msg": "String should have at most 200 characters", - "type": "string_too_long", + "input": "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", + "ctx": {"max_length": 200}, }, { - "ctx": {"ge": 0}, - "input": -1, + "type": "less_than_equal", "loc": ["body", 1, "amount"], - "msg": "Input should be greater than or equal to 0", - "type": "greater_than_equal", + "msg": "Input should be less than or equal to 1000000000000", + "input": 1000000000001, + "ctx": {"le": 1000000000000}, }, { - "ctx": {"le": 5000000000}, - "input": 5000000001, - "loc": ["body", 1, "price"], - "msg": "Input should be less than or equal to 5000000000", "type": "less_than_equal", + "loc": ["body", 1, "price"], + "msg": "Input should be less than or equal to 1000000000000", + "input": 1000000000001, + "ctx": {"le": 1000000000000}, }, { - "ctx": {"ge": 0}, - "input": -1, + "type": "less_than_equal", "loc": ["body", 1, "balance"], - "msg": "Input should be greater than or equal to 0", - "type": "greater_than_equal", + "msg": "Input should be less than or equal to 9223372036854775807", + "input": 9223372036854775808, + "ctx": {"le": 9223372036854775807}, }, { - "ctx": {"error": {}}, - "input": "2020/02/31", + "type": "value_error", "loc": ["body", 1, "acquisition_date"], "msg": "Value error, The date format must be YYYY/MM/DD", - "type": "value_error", + "input": "2020/02/31", + "ctx": {"error": {}}, }, ], } diff --git a/tests/test_app_routers_ledger_{token_address}_details_data_{data_id}_POST.py b/tests/test_app_routers_ledger_{token_address}_details_data_{data_id}_POST.py index 84fd7b03..2f83ee50 100644 --- a/tests/test_app_routers_ledger_{token_address}_details_data_{data_id}_POST.py +++ b/tests/test_app_routers_ledger_{token_address}_details_data_{data_id}_POST.py @@ -16,6 +16,7 @@ SPDX-License-Identifier: Apache-2.0 """ +import sys from unittest import mock from sqlalchemy import select @@ -116,6 +117,76 @@ def test_normal_1(self, mock_func, client, db): mock_func.assert_called_with(token_address, db) + # + # Max value + @mock.patch("app.routers.ledger.create_ledger") + def test_normal_2(self, mock_func, client, db): + user = config_eth_account("user1") + issuer_address = user["address"] + token_address = "0xABCdeF1234567890abcdEf123456789000000000" + data_id = "data_id_1" + + # prepare data + _token = Token() + _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.tx_hash = "" + _token.issuer_address = issuer_address + _token.token_address = token_address + _token.abi = {} + _token.version = TokenVersion.V_23_12 + db.add(_token) + + _details_1_data_1 = LedgerDetailsData() + _details_1_data_1.token_address = token_address + _details_1_data_1.data_id = data_id + _details_1_data_1.name = "name_test_0" + _details_1_data_1.address = "address_test_0" + _details_1_data_1.amount = 0 + _details_1_data_1.price = 1 + _details_1_data_1.balance = 2 + _details_1_data_1.acquisition_date = "2000/12/31" + db.add(_details_1_data_1) + + # request target API + req_param = [ + { + "name": "name_test_1", + "address": "address_test_1", + "amount": 1_000_000_000_000, + "price": 1_000_000_000_000, + "balance": sys.maxsize, + "acquisition_date": "2020/01/01", + }, + ] + resp = client.post( + self.base_url.format(token_address=token_address, data_id=data_id), + json=req_param, + headers={ + "issuer-address": issuer_address, + }, + ) + + # assertion + assert resp.status_code == 200 + assert resp.json() is None + + _details_data_list = db.scalars( + select(LedgerDetailsData).order_by(LedgerDetailsData.id) + ).all() + assert len(_details_data_list) == 1 + + _details_data = _details_data_list[0] + assert _details_data.id == 2 + assert _details_data.data_id == data_id + assert _details_data.name == "name_test_1" + assert _details_data.address == "address_test_1" + assert _details_data.amount == 1_000_000_000_000 + assert _details_data.price == 1_000_000_000_000 + assert _details_data.balance == sys.maxsize + assert _details_data.acquisition_date == "2020/01/01" + + mock_func.assert_called_with(token_address, db) + ########################################################################### # Error Case ########################################################################### @@ -213,9 +284,9 @@ def test_error_3(self, client, db): "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" "1", "address": "address_test_1", - "amount": 1_000_000_000_001, + "amount": -1, "price": -1, - "balance": 1_000_000_000_001 * 5_000_000_001, + "balance": -1, "acquisition_date": "2020/01/01a", }, { @@ -223,9 +294,9 @@ def test_error_3(self, client, db): "address": "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" "1", - "amount": -1, - "price": 5_000_000_001, - "balance": -1, + "amount": 1_000_000_000_001, + "price": 1_000_000_000_001, + "balance": sys.maxsize + 1, "acquisition_date": "2020/02/31", }, ] @@ -243,75 +314,74 @@ def test_error_3(self, client, db): "meta": {"code": 1, "title": "RequestValidationError"}, "detail": [ { - "ctx": {"max_length": 200}, - "input": "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", + "type": "string_too_long", "loc": ["body", 0, "name"], "msg": "String should have at most 200 characters", - "type": "string_too_long", + "input": "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", + "ctx": {"max_length": 200}, }, { - "ctx": {"le": 1000000000000}, - "input": 1000000000001, + "type": "greater_than_equal", "loc": ["body", 0, "amount"], - "msg": "Input should be less than or equal to 1000000000000", - "type": "less_than_equal", + "msg": "Input should be greater than or equal to 0", + "input": -1, + "ctx": {"ge": 0}, }, { - "ctx": {"ge": 0}, - "input": -1, + "type": "greater_than_equal", "loc": ["body", 0, "price"], "msg": "Input should be greater than or equal to 0", - "type": "greater_than_equal", + "input": -1, + "ctx": {"ge": 0}, }, { - "ctx": {"le": 5000000000000000000000}, - "input": 5000000001005000000001, + "type": "greater_than_equal", "loc": ["body", 0, "balance"], - "msg": "Input should be less than or equal to " - "5000000000000000000000", - "type": "less_than_equal", + "msg": "Input should be greater than or equal to 0", + "input": -1, + "ctx": {"ge": 0}, }, { - "ctx": {"max_length": 10}, - "input": "2020/01/01a", + "type": "string_too_long", "loc": ["body", 0, "acquisition_date"], "msg": "String should have at most 10 characters", - "type": "string_too_long", + "input": "2020/01/01a", + "ctx": {"max_length": 10}, }, { - "ctx": {"max_length": 200}, - "input": "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", + "type": "string_too_long", "loc": ["body", 1, "address"], "msg": "String should have at most 200 characters", - "type": "string_too_long", + "input": "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", + "ctx": {"max_length": 200}, }, { - "ctx": {"ge": 0}, - "input": -1, + "type": "less_than_equal", "loc": ["body", 1, "amount"], - "msg": "Input should be greater than or equal to 0", - "type": "greater_than_equal", + "msg": "Input should be less than or equal to 1000000000000", + "input": 1000000000001, + "ctx": {"le": 1000000000000}, }, { - "ctx": {"le": 5000000000}, - "input": 5000000001, - "loc": ["body", 1, "price"], - "msg": "Input should be less than or equal to 5000000000", "type": "less_than_equal", + "loc": ["body", 1, "price"], + "msg": "Input should be less than or equal to 1000000000000", + "input": 1000000000001, + "ctx": {"le": 1000000000000}, }, { - "ctx": {"ge": 0}, - "input": -1, + "type": "less_than_equal", "loc": ["body", 1, "balance"], - "msg": "Input should be greater than or equal to 0", - "type": "greater_than_equal", + "msg": "Input should be less than or equal to 9223372036854775807", + "input": 9223372036854775808, + "ctx": {"le": 9223372036854775807}, }, { - "ctx": {"error": {}}, - "input": "2020/02/31", + "type": "value_error", "loc": ["body", 1, "acquisition_date"], "msg": "Value error, The date format must be YYYY/MM/DD", - "type": "value_error", + "input": "2020/02/31", + "ctx": {"error": {}}, }, ], }