diff --git a/app/model/schema/__init__.py b/app/model/schema/__init__.py index a7ab5a90..21831189 100644 --- a/app/model/schema/__init__.py +++ b/app/model/schema/__init__.py @@ -118,10 +118,12 @@ from .position import ( ForceUnlockRequest, ListAllLockedPositionResponse, + ListAllLockedPositionsQuery, ListAllLockEventsQuery, ListAllLockEventsResponse, ListAllLockEventsSortItem, ListAllPositionResponse, + ListAllPositionsQuery, LockEventCategory, PositionResponse, ) diff --git a/app/model/schema/base/__init__.py b/app/model/schema/base/__init__.py index 4588c14c..5656f728 100644 --- a/app/model/schema/base/__init__.py +++ b/app/model/schema/base/__init__.py @@ -21,7 +21,9 @@ BasePaginationQuery, CURRENCY_str, EMPTY_str, + IbetShare, IbetShareContractVersion, + IbetStraightBond, IbetStraightBondContractVersion, KeyManagerType, MMDD_constr, diff --git a/app/model/schema/base/base.py b/app/model/schema/base/base.py index bd8a38be..2352eeed 100644 --- a/app/model/schema/base/base.py +++ b/app/model/schema/base/base.py @@ -34,12 +34,72 @@ class IbetStraightBondContractVersion(StrEnum): V_24_09 = "24_09" +class IbetStraightBond(BaseModel): + """IbetStraightBond schema""" + + issuer_address: str + token_address: str + name: str + symbol: str + total_supply: int + face_value: int + face_value_currency: str + redemption_date: str + redemption_value: int + redemption_value_currency: str + return_date: str + return_amount: str + purpose: str + interest_rate: float + interest_payment_date: list[str] + interest_payment_currency: str + base_fx_rate: float + transferable: bool + is_redeemed: bool + status: bool + is_offering: bool + tradable_exchange_contract_address: str + personal_info_contract_address: str + require_personal_info_registered: bool + contact_information: str + privacy_policy: str + transfer_approval_required: bool + memo: str + + class IbetShareContractVersion(StrEnum): V_22_12 = "22_12" V_24_06 = "24_06" V_24_09 = "24_09" +class IbetShare(BaseModel): + """IbetShare schema""" + + issuer_address: str + token_address: str + name: str + symbol: str + issue_price: int + principal_value: int + total_supply: int + dividends: float + dividend_record_date: str + dividend_payment_date: str + cancellation_date: str + transferable: bool + transfer_approval_required: bool + status: bool + is_offering: bool + tradable_exchange_contract_address: str + personal_info_contract_address: str + require_personal_info_registered: bool + contact_information: str + privacy_policy: str + is_canceled: bool + memo: str + + MMDD_constr = Annotated[ str, StringConstraints(pattern="^(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$") ] diff --git a/app/model/schema/position.py b/app/model/schema/position.py index d144eb4a..0ce25007 100644 --- a/app/model/schema/position.py +++ b/app/model/schema/position.py @@ -18,13 +18,20 @@ """ from enum import StrEnum -from typing import List, Optional +from typing import List, Optional, Union from pydantic import BaseModel, Field, PositiveInt, RootModel from app.model import EthereumAddress -from .base import BasePaginationQuery, ResultSet, SortOrder, TokenType +from .base import ( + BasePaginationQuery, + IbetShare, + IbetStraightBond, + ResultSet, + SortOrder, + TokenType, +) ############################ @@ -37,6 +44,9 @@ class Position(BaseModel): token_address: str = Field(description="Token address") token_type: TokenType = Field(description="Token type") token_name: str = Field(description="Token name") + token_attributes: Optional[Union[IbetStraightBond, IbetShare]] = Field( + description="Token attributes" + ) balance: int = Field(description="Balance") exchange_balance: int = Field(description="Balance on the exchange contract") exchange_commitment: int = Field(description="Commitment on the exchange contract") @@ -83,6 +93,22 @@ class LockEvent(BaseModel): ############################ # REQUEST ############################ +class ListAllPositionsQuery(BasePaginationQuery): + include_former_position: bool = Field( + False, + description="Whether to include positions that were held in the past but currently have a zero balance.", + ) + include_token_attributes: bool = Field( + False, + description="Whether to include token attribute information in the response.", + ) + token_type: Optional[TokenType] = Field(None, description="Token type") + + +class ListAllLockedPositionsQuery(BasePaginationQuery): + token_type: Optional[TokenType] = Field(None, description="Token type") + + class ListAllLockEventsSortItem(StrEnum): token_address = "token_address" lock_address = "lock_address" @@ -117,8 +143,6 @@ class ForceUnlockRequest(BaseModel): ############################ # RESPONSE ############################ - - class PositionResponse(RootModel[Position]): """Position schema (Response)""" diff --git a/app/model/schema/token.py b/app/model/schema/token.py index 69f3e37c..45be4cf2 100644 --- a/app/model/schema/token.py +++ b/app/model/schema/token.py @@ -32,7 +32,9 @@ BasePaginationQuery, CURRENCY_str, EMPTY_str, + IbetShare, IbetShareContractVersion, + IbetStraightBond, IbetStraightBondContractVersion, MMDD_constr, ResultSet, @@ -466,69 +468,19 @@ class TokenAddressResponse(BaseModel): token_status: int -class IbetStraightBondResponse(BaseModel): +class IbetStraightBondResponse(IbetStraightBond): """ibet Straight Bond schema (Response)""" - issuer_address: str - token_address: str - name: str - symbol: str - total_supply: int - face_value: int - face_value_currency: str - redemption_date: str - redemption_value: int - redemption_value_currency: str - return_date: str - return_amount: str - purpose: str - interest_rate: float - interest_payment_date: list[str] - interest_payment_currency: str - base_fx_rate: float - transferable: bool - is_redeemed: bool - status: bool - is_offering: bool - tradable_exchange_contract_address: str - personal_info_contract_address: str - require_personal_info_registered: bool - contact_information: str - privacy_policy: str issue_datetime: str token_status: int - transfer_approval_required: bool - memo: str contract_version: IbetStraightBondContractVersion -class IbetShareResponse(BaseModel): +class IbetShareResponse(IbetShare): """ibet Share schema (Response)""" - issuer_address: str - token_address: str - name: str - symbol: str - issue_price: int - principal_value: int - total_supply: int - dividends: float - dividend_record_date: str - dividend_payment_date: str - cancellation_date: str - transferable: bool - transfer_approval_required: bool - status: bool - is_offering: bool - tradable_exchange_contract_address: str - personal_info_contract_address: str - require_personal_info_registered: bool - contact_information: str - privacy_policy: str issue_datetime: str token_status: int - is_canceled: bool - memo: str contract_version: IbetShareContractVersion diff --git a/app/routers/issuer/position.py b/app/routers/issuer/position.py index 87456b99..0293deeb 100644 --- a/app/routers/issuer/position.py +++ b/app/routers/issuer/position.py @@ -52,10 +52,12 @@ from app.model.schema import ( ForceUnlockRequest, ListAllLockedPositionResponse, + ListAllLockedPositionsQuery, ListAllLockEventsQuery, ListAllLockEventsResponse, ListAllLockEventsSortItem, ListAllPositionResponse, + ListAllPositionsQuery, LockEventCategory, PositionResponse, ) @@ -83,12 +85,9 @@ ) async def list_all_positions( db: DBAsyncSession, - account_address: str, - issuer_address: Optional[str] = Header(None), - include_former_position: bool = False, - token_type: Optional[TokenType] = Query(None), - offset: Optional[int] = Query(None), - limit: Optional[int] = Query(None), + account_address: Annotated[str, Path()], + request_query: Annotated[ListAllPositionsQuery, Query()], + issuer_address: Annotated[Optional[str], Header()] = None, ): """List all positions""" @@ -119,7 +118,7 @@ async def list_all_positions( ) ) - if not include_former_position: + if not request_query.include_former_position: stmt = stmt.where( or_( IDXPosition.balance != 0, @@ -138,16 +137,16 @@ async def list_all_positions( total = await db.scalar(select(func.count()).select_from(stmt.subquery())) # Search Filter - if token_type is not None: - stmt = stmt.where(Token.type == token_type.value) + if request_query.token_type is not None: + stmt = stmt.where(Token.type == request_query.token_type) count = await db.scalar(select(func.count()).select_from(stmt.subquery())) # Pagination - if limit is not None: - stmt = stmt.limit(limit) - if offset is not None: - stmt = stmt.offset(offset) + if request_query.limit is not None: + stmt = stmt.limit(request_query.limit) + if request_query.offset is not None: + stmt = stmt.offset(request_query.offset) _position_list: Sequence[tuple[IDXPosition, int, Token]] = ( (await db.execute(stmt)).tuples().all() @@ -155,20 +154,25 @@ async def list_all_positions( positions = [] for _position, _locked, _token in _position_list: - # Get Token Name - token_name = None - if _token.type == TokenType.IBET_STRAIGHT_BOND.value: - _bond = await IbetStraightBondContract(_token.token_address).get() - token_name = _bond.name - elif _token.type == TokenType.IBET_SHARE.value: - _share = await IbetShareContract(_token.token_address).get() - token_name = _share.name + # Get Token Attributes + token_attr = None + if _token.type == TokenType.IBET_STRAIGHT_BOND: + token_attr = await IbetStraightBondContract(_token.token_address).get() + elif _token.type == TokenType.IBET_SHARE: + token_attr = await IbetShareContract(_token.token_address).get() + positions.append( { "issuer_address": _token.issuer_address, "token_address": _token.token_address, "token_type": _token.type, - "token_name": token_name, + "token_name": token_attr.name if token_attr is not None else None, + "token_attributes": token_attr.__dict__ + if ( + request_query.include_token_attributes is True + and token_attr is not None + ) + else None, "balance": _position.balance, "exchange_balance": _position.exchange_balance, "exchange_commitment": _position.exchange_commitment, @@ -180,8 +184,8 @@ async def list_all_positions( resp = { "result_set": { "count": count, - "offset": offset, - "limit": limit, + "offset": request_query.offset, + "limit": request_query.limit, "total": total, }, "positions": positions, @@ -199,11 +203,9 @@ async def list_all_positions( ) async def list_all_locked_position( db: DBAsyncSession, - account_address: str, - issuer_address: Optional[str] = Header(None), - token_type: Optional[TokenType] = Query(None), - offset: Optional[int] = Query(None), - limit: Optional[int] = Query(None), + account_address: Annotated[str, Path()], + request_query: Annotated[ListAllLockedPositionsQuery, Query()], + issuer_address: Annotated[Optional[str], Header()] = None, ): """List all locked position""" @@ -230,16 +232,16 @@ async def list_all_locked_position( total = await db.scalar(select(func.count()).select_from(stmt.subquery())) # Search Filter - if token_type is not None: - stmt = stmt.where(Token.type == token_type.value) + if request_query.token_type is not None: + stmt = stmt.where(Token.type == request_query.token_type) count = await db.scalar(select(func.count()).select_from(stmt.subquery())) # Pagination - if limit is not None: - stmt = stmt.limit(limit) - if offset is not None: - stmt = stmt.offset(offset) + if request_query.limit is not None: + stmt = stmt.limit(request_query.limit) + if request_query.offset is not None: + stmt = stmt.offset(request_query.offset) _position_list: Sequence[tuple[IDXLockedPosition, Token]] = ( (await db.execute(stmt)).tuples().all() @@ -269,8 +271,8 @@ async def list_all_locked_position( resp = { "result_set": { "count": count, - "offset": offset, - "limit": limit, + "offset": request_query.offset, + "limit": request_query.limit, "total": total, }, "locked_positions": positions, @@ -287,7 +289,7 @@ async def list_all_locked_position( ) async def list_account_lock_unlock_events( db: DBAsyncSession, - account_address: str, + account_address: Annotated[str, Path()], request_query: Annotated[ListAllLockEventsQuery, Query()], issuer_address: Annotated[Optional[str], Header()] = None, ): @@ -634,20 +636,19 @@ async def retrieve_position( balance=0, exchange_balance=0, exchange_commitment=0, pending_transfer=0 ) - # Get Token Name - token_name = None - if _token.type == TokenType.IBET_STRAIGHT_BOND.value: - _bond = await IbetStraightBondContract(_token.token_address).get() - token_name = _bond.name - elif _token.type == TokenType.IBET_SHARE.value: - _share = await IbetShareContract(_token.token_address).get() - token_name = _share.name + # Get Token Attributes + token_attr = None + if _token.type == TokenType.IBET_STRAIGHT_BOND: + token_attr = await IbetStraightBondContract(_token.token_address).get() + elif _token.type == TokenType.IBET_SHARE: + token_attr = await IbetShareContract(_token.token_address).get() resp = { "issuer_address": _token.issuer_address, "token_address": _token.token_address, "token_type": _token.type, - "token_name": token_name, + "token_name": token_attr.name if token_attr is not None else None, + "token_attributes": token_attr.__dict__ if token_attr is not None else None, "balance": _position.balance, "exchange_balance": _position.exchange_balance, "exchange_commitment": _position.exchange_commitment, diff --git a/docs/ibet_prime.yaml b/docs/ibet_prime.yaml index bb977282..2493e261 100644 --- a/docs/ibet_prime.yaml +++ b/docs/ibet_prime.yaml @@ -4848,37 +4848,58 @@ paths: schema: type: string title: Account Address - - name: include_former_position - in: query - required: false - schema: - type: boolean - default: false - title: Include Former Position - - name: token_type - in: query - required: false - schema: - anyOf: - - $ref: '#/components/schemas/TokenType' - - type: 'null' - title: Token Type - name: offset in: query required: false schema: anyOf: - type: integer + minimum: 0 - type: 'null' + description: Offset for pagination title: Offset + description: Offset for pagination - name: limit in: query required: false schema: anyOf: - type: integer + minimum: 0 - type: 'null' + description: Limit for pagination title: Limit + description: Limit for pagination + - name: include_former_position + in: query + required: false + schema: + type: boolean + description: Whether to include positions that were held in the past but + currently have a zero balance. + default: false + title: Include Former Position + description: Whether to include positions that were held in the past but + currently have a zero balance. + - name: include_token_attributes + in: query + required: false + schema: + type: boolean + description: Whether to include token attribute information in the response. + default: false + title: Include Token Attributes + description: Whether to include token attribute information in the response. + - name: token_type + in: query + required: false + schema: + anyOf: + - $ref: '#/components/schemas/TokenType' + - type: 'null' + description: Token type + title: Token Type + description: Token type - name: issuer-address in: header required: false @@ -4914,30 +4935,38 @@ paths: schema: type: string title: Account Address - - name: token_type - in: query - required: false - schema: - anyOf: - - $ref: '#/components/schemas/TokenType' - - type: 'null' - title: Token Type - name: offset in: query required: false schema: anyOf: - type: integer + minimum: 0 - type: 'null' + description: Offset for pagination title: Offset + description: Offset for pagination - name: limit in: query required: false schema: anyOf: - type: integer + minimum: 0 - type: 'null' + description: Limit for pagination title: Limit + description: Limit for pagination + - name: token_type + in: query + required: false + schema: + anyOf: + - $ref: '#/components/schemas/TokenType' + - type: 'null' + description: Token type + title: Token Type + description: Token type - name: issuer-address in: header required: false @@ -12175,6 +12204,100 @@ components: - holders title: HoldersResponse description: Holders schema (Response) + IbetShare: + properties: + issuer_address: + type: string + title: Issuer Address + token_address: + type: string + title: Token Address + name: + type: string + title: Name + symbol: + type: string + title: Symbol + issue_price: + type: integer + title: Issue Price + principal_value: + type: integer + title: Principal Value + total_supply: + type: integer + title: Total Supply + dividends: + type: number + title: Dividends + dividend_record_date: + type: string + title: Dividend Record Date + dividend_payment_date: + type: string + title: Dividend Payment Date + cancellation_date: + type: string + title: Cancellation Date + transferable: + type: boolean + title: Transferable + transfer_approval_required: + type: boolean + title: Transfer Approval Required + status: + type: boolean + title: Status + is_offering: + type: boolean + title: Is Offering + tradable_exchange_contract_address: + type: string + title: Tradable Exchange Contract Address + personal_info_contract_address: + type: string + title: Personal Info Contract Address + require_personal_info_registered: + type: boolean + title: Require Personal Info Registered + contact_information: + type: string + title: Contact Information + privacy_policy: + type: string + title: Privacy Policy + is_canceled: + type: boolean + title: Is Canceled + memo: + type: string + title: Memo + type: object + required: + - issuer_address + - token_address + - name + - symbol + - issue_price + - principal_value + - total_supply + - dividends + - dividend_record_date + - dividend_payment_date + - cancellation_date + - transferable + - transfer_approval_required + - status + - is_offering + - tradable_exchange_contract_address + - personal_info_contract_address + - require_personal_info_registered + - contact_information + - privacy_policy + - is_canceled + - memo + title: IbetShare + description: IbetShare schema IbetShareAdditionalIssue: properties: account_address: @@ -12408,18 +12531,18 @@ components: privacy_policy: type: string title: Privacy Policy - issue_datetime: - type: string - title: Issue Datetime - token_status: - type: integer - title: Token Status is_canceled: type: boolean title: Is Canceled memo: type: string title: Memo + issue_datetime: + type: string + title: Issue Datetime + token_status: + type: integer + title: Token Status contract_version: $ref: '#/components/schemas/IbetShareContractVersion' type: object @@ -12444,10 +12567,10 @@ components: - require_personal_info_registered - contact_information - privacy_policy - - issue_datetime - - token_status - is_canceled - memo + - issue_datetime + - token_status - contract_version title: IbetShareResponse description: ibet Share schema (Response) @@ -12593,6 +12716,126 @@ components: type: object title: IbetShareUpdate description: ibet Share schema (Update) + IbetStraightBond: + properties: + issuer_address: + type: string + title: Issuer Address + token_address: + type: string + title: Token Address + name: + type: string + title: Name + symbol: + type: string + title: Symbol + total_supply: + type: integer + title: Total Supply + face_value: + type: integer + title: Face Value + face_value_currency: + type: string + title: Face Value Currency + redemption_date: + type: string + title: Redemption Date + redemption_value: + type: integer + title: Redemption Value + redemption_value_currency: + type: string + title: Redemption Value Currency + return_date: + type: string + title: Return Date + return_amount: + type: string + title: Return Amount + purpose: + type: string + title: Purpose + interest_rate: + type: number + title: Interest Rate + interest_payment_date: + items: + type: string + type: array + title: Interest Payment Date + interest_payment_currency: + type: string + title: Interest Payment Currency + base_fx_rate: + type: number + title: Base Fx Rate + transferable: + type: boolean + title: Transferable + is_redeemed: + type: boolean + title: Is Redeemed + status: + type: boolean + title: Status + is_offering: + type: boolean + title: Is Offering + tradable_exchange_contract_address: + type: string + title: Tradable Exchange Contract Address + personal_info_contract_address: + type: string + title: Personal Info Contract Address + require_personal_info_registered: + type: boolean + title: Require Personal Info Registered + contact_information: + type: string + title: Contact Information + privacy_policy: + type: string + title: Privacy Policy + transfer_approval_required: + type: boolean + title: Transfer Approval Required + memo: + type: string + title: Memo + type: object + required: + - issuer_address + - token_address + - name + - symbol + - total_supply + - face_value + - face_value_currency + - redemption_date + - redemption_value + - redemption_value_currency + - return_date + - return_amount + - purpose + - interest_rate + - interest_payment_date + - interest_payment_currency + - base_fx_rate + - transferable + - is_redeemed + - status + - is_offering + - tradable_exchange_contract_address + - personal_info_contract_address + - require_personal_info_registered + - contact_information + - privacy_policy + - transfer_approval_required + - memo + title: IbetStraightBond + description: IbetStraightBond schema IbetStraightBondAdditionalIssue: properties: account_address: @@ -12888,18 +13131,18 @@ components: privacy_policy: type: string title: Privacy Policy - issue_datetime: - type: string - title: Issue Datetime - token_status: - type: integer - title: Token Status transfer_approval_required: type: boolean title: Transfer Approval Required memo: type: string title: Memo + issue_datetime: + type: string + title: Issue Datetime + token_status: + type: integer + title: Token Status contract_version: $ref: '#/components/schemas/IbetStraightBondContractVersion' type: object @@ -12930,10 +13173,10 @@ components: - require_personal_info_registered - contact_information - privacy_policy - - issue_datetime - - token_status - transfer_approval_required - memo + - issue_datetime + - token_status - contract_version title: IbetStraightBondResponse description: ibet Straight Bond schema (Response) @@ -14377,6 +14620,13 @@ components: type: string title: Token Name description: Token name + token_attributes: + anyOf: + - $ref: '#/components/schemas/IbetStraightBond' + - $ref: '#/components/schemas/IbetShare' + - type: 'null' + title: Token Attributes + description: Token attributes balance: type: integer title: Balance @@ -14403,6 +14653,7 @@ components: - token_address - token_type - token_name + - token_attributes - balance - exchange_balance - exchange_commitment diff --git a/tests/app/test_positions_ListAllLockedPosition.py b/tests/app/test_positions_ListAllLockedPosition.py index 64fe657e..d89a2a74 100644 --- a/tests/app/test_positions_ListAllLockedPosition.py +++ b/tests/app/test_positions_ListAllLockedPosition.py @@ -692,13 +692,6 @@ def test_error_1_2(self, client, db): assert resp.json() == { "meta": {"code": 1, "title": "RequestValidationError"}, "detail": [ - { - "ctx": {"expected": "'IbetStraightBond' or 'IbetShare'"}, - "input": "test", - "loc": ["query", "token_type"], - "msg": "Input should be 'IbetStraightBond' or 'IbetShare'", - "type": "enum", - }, { "input": "test", "loc": ["query", "offset"], @@ -713,5 +706,12 @@ def test_error_1_2(self, client, db): "as an integer", "type": "int_parsing", }, + { + "ctx": {"expected": "'IbetStraightBond' or 'IbetShare'"}, + "input": "test", + "loc": ["query", "token_type"], + "msg": "Input should be 'IbetStraightBond' or 'IbetShare'", + "type": "enum", + }, ], } diff --git a/tests/app/test_positions_ListAllPositions.py b/tests/app/test_positions_ListAllPositions.py index b6799046..463f76e8 100644 --- a/tests/app/test_positions_ListAllPositions.py +++ b/tests/app/test_positions_ListAllPositions.py @@ -20,7 +20,13 @@ from unittest import mock from app.model.blockchain import IbetShareContract, IbetStraightBondContract -from app.model.db import IDXLockedPosition, IDXPosition, Token, TokenType, TokenVersion +from app.model.db import ( + IDXLockedPosition, + IDXPosition, + Token, + TokenType, + TokenVersion, +) class TestListAllPositions: @@ -35,20 +41,22 @@ class TestListAllPositions: # 0 record def test_normal_1(self, client, db): account_address = "0x1234567890123456789012345678900000000000" + token_address = "0x1234567890123456789012345678900000000010" + issuer_address = "0x1234567890123456789012345678900000000100" # prepare data: Token _token = Token() - _token.token_address = "0x1234567890123456789012345678900000000010" - _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.token_address = token_address + _token.issuer_address = issuer_address + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) # prepare data: Position _position = IDXPosition() - _position.token_address = "0x1234567890123456789012345678900000000010" + _position.token_address = token_address _position.account_address = ( "0x1234567890123456789012345678900000000001" # not target ) @@ -90,9 +98,9 @@ def test_normal_2(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = token_address_1 _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -157,8 +165,9 @@ def test_normal_2(self, mock_IbetStraightBondContract_get, client, db): { "issuer_address": issuer_address, "token_address": token_address_1, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": None, "balance": 10, "exchange_balance": 11, "exchange_commitment": 12, @@ -185,9 +194,9 @@ def test_normal_3_1( _token = Token() _token.token_address = token_address_1 _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -224,9 +233,9 @@ def test_normal_3_1( _token = Token() _token.token_address = token_address_2 _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -263,9 +272,9 @@ def test_normal_3_1( _token = Token() _token.token_address = token_address_3 _token.issuer_address = issuer_address - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -328,8 +337,9 @@ def test_normal_3_1( { "issuer_address": issuer_address, "token_address": token_address_1, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": None, "balance": 10, "exchange_balance": 11, "exchange_commitment": 12, @@ -339,8 +349,9 @@ def test_normal_3_1( { "issuer_address": issuer_address, "token_address": token_address_2, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_2", + "token_attributes": None, "balance": 20, "exchange_balance": 21, "exchange_commitment": 22, @@ -350,8 +361,9 @@ def test_normal_3_1( { "issuer_address": issuer_address, "token_address": token_address_3, - "token_type": TokenType.IBET_SHARE.value, + "token_type": TokenType.IBET_SHARE, "token_name": "test_share_1", + "token_attributes": None, "balance": 30, "exchange_balance": 31, "exchange_commitment": 32, @@ -378,9 +390,9 @@ def test_normal_3_2( _token = Token() _token.token_address = token_address_1 _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -398,9 +410,9 @@ def test_normal_3_2( _token = Token() _token.token_address = token_address_2 _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -428,9 +440,9 @@ def test_normal_3_2( _token = Token() _token.token_address = token_address_3 _token.issuer_address = issuer_address - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -484,8 +496,9 @@ def test_normal_3_2( { "issuer_address": issuer_address, "token_address": token_address_1, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": None, "balance": 10, "exchange_balance": 11, "exchange_commitment": 12, @@ -495,8 +508,9 @@ def test_normal_3_2( { "issuer_address": issuer_address, "token_address": token_address_2, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_2", + "token_attributes": None, "balance": 0, "exchange_balance": 0, "exchange_commitment": 22, @@ -519,9 +533,9 @@ def test_normal_4( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000010" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -541,9 +555,9 @@ def test_normal_4( _token.issuer_address = ( "0x1234567890123456789012345678900000000101" # not target ) - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -561,9 +575,9 @@ def test_normal_4( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000012" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -608,8 +622,9 @@ def test_normal_4( { "issuer_address": "0x1234567890123456789012345678900000000100", "token_address": "0x1234567890123456789012345678900000000010", - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": None, "balance": 10, "exchange_balance": 11, "exchange_commitment": 12, @@ -619,8 +634,9 @@ def test_normal_4( { "issuer_address": "0x1234567890123456789012345678900000000100", "token_address": "0x1234567890123456789012345678900000000012", - "token_type": TokenType.IBET_SHARE.value, + "token_type": TokenType.IBET_SHARE, "token_name": "test_share_1", + "token_attributes": None, "balance": 30, "exchange_balance": 31, "exchange_commitment": 32, @@ -642,9 +658,9 @@ def test_normal_5_1(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = "0x1234567890123456789012345678900000000010" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -662,9 +678,9 @@ def test_normal_5_1(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = "0x1234567890123456789012345678900000000011" _token.issuer_address = "0x1234567890123456789012345678900000000101" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -682,9 +698,9 @@ def test_normal_5_1(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = "0x1234567890123456789012345678900000000012" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -710,7 +726,7 @@ def test_normal_5_1(self, mock_IbetStraightBondContract_get, client, db): # request target api resp = client.get( self.base_url.format(account_address=account_address), - params={"token_type": TokenType.IBET_STRAIGHT_BOND.value}, + params={"token_type": TokenType.IBET_STRAIGHT_BOND}, ) # assertion @@ -726,8 +742,9 @@ def test_normal_5_1(self, mock_IbetStraightBondContract_get, client, db): { "issuer_address": "0x1234567890123456789012345678900000000100", "token_address": "0x1234567890123456789012345678900000000010", - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": None, "balance": 10, "exchange_balance": 11, "exchange_commitment": 12, @@ -737,8 +754,9 @@ def test_normal_5_1(self, mock_IbetStraightBondContract_get, client, db): { "issuer_address": "0x1234567890123456789012345678900000000101", "token_address": "0x1234567890123456789012345678900000000011", - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_2", + "token_attributes": None, "balance": 20, "exchange_balance": 21, "exchange_commitment": 22, @@ -760,9 +778,9 @@ def test_normal_5_2(self, mock_IbetShareContract_get, client, db): _token = Token() _token.token_address = "0x1234567890123456789012345678900000000010" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -780,9 +798,9 @@ def test_normal_5_2(self, mock_IbetShareContract_get, client, db): _token = Token() _token.token_address = "0x1234567890123456789012345678900000000011" _token.issuer_address = "0x1234567890123456789012345678900000000101" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -800,9 +818,9 @@ def test_normal_5_2(self, mock_IbetShareContract_get, client, db): _token = Token() _token.token_address = "0x1234567890123456789012345678900000000012" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -826,7 +844,7 @@ def test_normal_5_2(self, mock_IbetShareContract_get, client, db): # request target api resp = client.get( self.base_url.format(account_address=account_address), - params={"token_type": TokenType.IBET_SHARE.value}, + params={"token_type": TokenType.IBET_SHARE}, ) # assertion @@ -842,8 +860,9 @@ def test_normal_5_2(self, mock_IbetShareContract_get, client, db): { "issuer_address": "0x1234567890123456789012345678900000000100", "token_address": "0x1234567890123456789012345678900000000012", - "token_type": TokenType.IBET_SHARE.value, + "token_type": TokenType.IBET_SHARE, "token_name": "test_share_1", + "token_attributes": None, "balance": 30, "exchange_balance": 31, "exchange_commitment": 32, @@ -867,9 +886,9 @@ def test_normal_5_3( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000010" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -887,9 +906,9 @@ def test_normal_5_3( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000011" _token.issuer_address = "0x1234567890123456789012345678900000000101" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -907,9 +926,9 @@ def test_normal_5_3( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000012" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -927,9 +946,9 @@ def test_normal_5_3( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000013" _token.issuer_address = "0x1234567890123456789012345678900000000101" - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -976,8 +995,9 @@ def test_normal_5_3( { "issuer_address": "0x1234567890123456789012345678900000000100", "token_address": "0x1234567890123456789012345678900000000010", - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": None, "balance": 10, "exchange_balance": 11, "exchange_commitment": 12, @@ -987,8 +1007,9 @@ def test_normal_5_3( { "issuer_address": "0x1234567890123456789012345678900000000101", "token_address": "0x1234567890123456789012345678900000000011", - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_2", + "token_attributes": None, "balance": 0, "exchange_balance": 0, "exchange_commitment": 0, @@ -998,8 +1019,9 @@ def test_normal_5_3( { "issuer_address": "0x1234567890123456789012345678900000000100", "token_address": "0x1234567890123456789012345678900000000012", - "token_type": TokenType.IBET_SHARE.value, + "token_type": TokenType.IBET_SHARE, "token_name": "test_share_1", + "token_attributes": None, "balance": 30, "exchange_balance": 20, "exchange_commitment": 10, @@ -1009,8 +1031,9 @@ def test_normal_5_3( { "issuer_address": "0x1234567890123456789012345678900000000101", "token_address": "0x1234567890123456789012345678900000000013", - "token_type": TokenType.IBET_SHARE.value, + "token_type": TokenType.IBET_SHARE, "token_name": "test_share_2", + "token_attributes": None, "balance": 0, "exchange_balance": 0, "exchange_commitment": 0, @@ -1033,9 +1056,9 @@ def test_normal_6( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000010" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -1053,9 +1076,9 @@ def test_normal_6( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000011" _token.issuer_address = "0x1234567890123456789012345678900000000101" - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -1073,9 +1096,9 @@ def test_normal_6( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000012" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -1093,9 +1116,9 @@ def test_normal_6( _token = Token() _token.token_address = "0x1234567890123456789012345678900000000013" _token.issuer_address = "0x1234567890123456789012345678900000000100" - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -1141,8 +1164,9 @@ def test_normal_6( { "issuer_address": "0x1234567890123456789012345678900000000101", "token_address": "0x1234567890123456789012345678900000000011", - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_2", + "token_attributes": None, "balance": 20, "exchange_balance": 21, "exchange_commitment": 22, @@ -1152,8 +1176,9 @@ def test_normal_6( { "issuer_address": "0x1234567890123456789012345678900000000100", "token_address": "0x1234567890123456789012345678900000000012", - "token_type": TokenType.IBET_SHARE.value, + "token_type": TokenType.IBET_SHARE, "token_name": "test_share_1", + "token_attributes": None, "balance": 30, "exchange_balance": 31, "exchange_commitment": 32, @@ -1163,6 +1188,261 @@ def test_normal_6( ], } + # + # include_token_attributes: True + # - IbetStraightBond + @mock.patch("app.model.blockchain.token.IbetStraightBondContract.get") + def test_normal_7_1(self, mock_IbetStraightBondContract_get, client, db): + issuer_address = "0x1234567890123456789012345678900000000100" + account_address = "0x1234567890123456789012345678900000000000" + other_account_address = "0x1234567890123456789012345678911111111111" + token_address_1 = "0x1234567890123456789012345678900000000010" + + # prepare data: Token + _token = Token() + _token.token_address = token_address_1 + _token.issuer_address = issuer_address + _token.type = TokenType.IBET_STRAIGHT_BOND + _token.tx_hash = "" + _token.abi = {} + _token.version = TokenVersion.V_24_09 + db.add(_token) + + # prepare data: Position + _position = IDXPosition() + _position.token_address = token_address_1 + _position.account_address = account_address + _position.balance = 10 + _position.exchange_balance = 11 + _position.exchange_commitment = 12 + _position.pending_transfer = 13 + db.add(_position) + + # prepare data: Locked Position + _locked_position = IDXLockedPosition() + _locked_position.token_address = token_address_1 + _locked_position.lock_address = ( + "0x1234567890123456789012345678900000000001" # lock address 1 + ) + _locked_position.account_address = account_address + _locked_position.value = 5 + db.add(_locked_position) + + _locked_position = IDXLockedPosition() + _locked_position.token_address = token_address_1 + _locked_position.lock_address = ( + "0x1234567890123456789012345678900000000002" # lock address 2 + ) + _locked_position.account_address = account_address + _locked_position.value = 5 + db.add(_locked_position) + + _locked_position = IDXLockedPosition() + _locked_position.token_address = token_address_1 + _locked_position.lock_address = "0x1234567890123456789012345678900000000002" + _locked_position.account_address = other_account_address # not to be included + _locked_position.value = 5 + db.add(_locked_position) + + db.commit() + + # mock + bond_1 = IbetStraightBondContract() + token_attr = { + "issuer_address": issuer_address, + "token_address": token_address_1, + "name": "テスト債券-test", + "symbol": "TEST-test", + "total_supply": 9999999, + "contact_information": "test1", + "privacy_policy": "test2", + "tradable_exchange_contract_address": "0x1234567890123456789012345678901234567890", + "status": False, + "personal_info_contract_address": "0x1234567890123456789012345678901234567891", + "require_personal_info_registered": True, + "transferable": True, + "is_offering": True, + "transfer_approval_required": True, + "face_value": 9999998, + "face_value_currency": "JPY", + "interest_rate": 99.999, + "interest_payment_date": [ + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + ], + "interest_payment_currency": "JPY", + "redemption_date": "99991231", + "redemption_value": 9999997, + "redemption_value_currency": "JPY", + "return_date": "99991230", + "return_amount": "return_amount-test", + "base_fx_rate": 123.456789, + "purpose": "purpose-test", + "memo": "memo-test", + "is_redeemed": True, + } + bond_1.__dict__ = token_attr + mock_IbetStraightBondContract_get.side_effect = [bond_1] + + # request target api + resp = client.get( + self.base_url.format(account_address=account_address), + params={"include_token_attributes": True}, + ) + + # assertion + assert resp.status_code == 200 + assert resp.json() == { + "result_set": { + "count": 1, + "offset": None, + "limit": None, + "total": 1, + }, + "positions": [ + { + "issuer_address": issuer_address, + "token_address": token_address_1, + "token_type": TokenType.IBET_STRAIGHT_BOND, + "token_name": "テスト債券-test", + "token_attributes": token_attr, + "balance": 10, + "exchange_balance": 11, + "exchange_commitment": 12, + "pending_transfer": 13, + "locked": 10, + }, + ], + } + + # + # include_token_attributes: True + # - IbetShare + @mock.patch("app.model.blockchain.token.IbetShareContract.get") + def test_normal_7_2(self, mock_IbetShareContract_get, client, db): + issuer_address = "0x1234567890123456789012345678900000000100" + account_address = "0x1234567890123456789012345678900000000000" + other_account_address = "0x1234567890123456789012345678911111111111" + token_address_1 = "0x1234567890123456789012345678900000000010" + + # prepare data: Token + _token = Token() + _token.token_address = token_address_1 + _token.issuer_address = issuer_address + _token.type = TokenType.IBET_SHARE + _token.tx_hash = "" + _token.abi = {} + _token.version = TokenVersion.V_24_09 + db.add(_token) + + # prepare data: Position + _position = IDXPosition() + _position.token_address = token_address_1 + _position.account_address = account_address + _position.balance = 10 + _position.exchange_balance = 11 + _position.exchange_commitment = 12 + _position.pending_transfer = 13 + db.add(_position) + + # prepare data: Locked Position + _locked_position = IDXLockedPosition() + _locked_position.token_address = token_address_1 + _locked_position.lock_address = ( + "0x1234567890123456789012345678900000000001" # lock address 1 + ) + _locked_position.account_address = account_address + _locked_position.value = 5 + db.add(_locked_position) + + _locked_position = IDXLockedPosition() + _locked_position.token_address = token_address_1 + _locked_position.lock_address = ( + "0x1234567890123456789012345678900000000002" # lock address 2 + ) + _locked_position.account_address = account_address + _locked_position.value = 5 + db.add(_locked_position) + + _locked_position = IDXLockedPosition() + _locked_position.token_address = token_address_1 + _locked_position.lock_address = "0x1234567890123456789012345678900000000002" + _locked_position.account_address = other_account_address # not to be included + _locked_position.value = 5 + db.add(_locked_position) + + db.commit() + + # mock + share_1 = IbetShareContract() + token_attr = { + "issuer_address": issuer_address, + "token_address": token_address_1, + "name": "テスト株式-test", + "symbol": "TEST-test", + "total_supply": 999999, + "contact_information": "test1", + "privacy_policy": "test2", + "tradable_exchange_contract_address": "0x1234567890123456789012345678901234567890", + "status": False, + "personal_info_contract_address": "0x1234567890123456789012345678901234567891", + "require_personal_info_registered": False, + "transferable": True, + "is_offering": True, + "transfer_approval_required": True, + "issue_price": 999997, + "cancellation_date": "99991231", + "memo": "memo_test", + "principal_value": 999998, + "is_canceled": True, + "dividends": 9.99, + "dividend_record_date": "99991230", + "dividend_payment_date": "99991229", + } + share_1.__dict__ = token_attr + mock_IbetShareContract_get.side_effect = [share_1] + + # request target api + resp = client.get( + self.base_url.format(account_address=account_address), + params={"include_token_attributes": True}, + ) + + # assertion + assert resp.status_code == 200 + assert resp.json() == { + "result_set": { + "count": 1, + "offset": None, + "limit": None, + "total": 1, + }, + "positions": [ + { + "issuer_address": issuer_address, + "token_address": token_address_1, + "token_type": TokenType.IBET_SHARE, + "token_name": "テスト株式-test", + "token_attributes": token_attr, + "balance": 10, + "exchange_balance": 11, + "exchange_commitment": 12, + "pending_transfer": 13, + "locked": 10, + }, + ], + } + ########################################################################### # Error Case ########################################################################### @@ -1216,13 +1496,6 @@ def test_error_1_2(self, client, db): assert resp.json() == { "meta": {"code": 1, "title": "RequestValidationError"}, "detail": [ - { - "ctx": {"expected": "'IbetStraightBond' or 'IbetShare'"}, - "input": "test", - "loc": ["query", "token_type"], - "msg": "Input should be 'IbetStraightBond' or 'IbetShare'", - "type": "enum", - }, { "input": "test", "loc": ["query", "offset"], @@ -1237,5 +1510,12 @@ def test_error_1_2(self, client, db): "as an integer", "type": "int_parsing", }, + { + "ctx": {"expected": "'IbetStraightBond' or 'IbetShare'"}, + "input": "test", + "loc": ["query", "token_type"], + "msg": "Input should be 'IbetStraightBond' or 'IbetShare'", + "type": "enum", + }, ], } diff --git a/tests/app/test_positions_RetrieveTokenPositionForAccount.py b/tests/app/test_positions_RetrieveTokenPositionForAccount.py index acf1e54a..915d572a 100644 --- a/tests/app/test_positions_RetrieveTokenPositionForAccount.py +++ b/tests/app/test_positions_RetrieveTokenPositionForAccount.py @@ -45,9 +45,9 @@ def test_normal_1_1(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = token_address _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -91,7 +91,50 @@ def test_normal_1_1(self, mock_IbetStraightBondContract_get, client, db): # mock bond_1 = IbetStraightBondContract() - bond_1.name = "test_bond_1" + token_attr = { + "issuer_address": issuer_address, + "token_address": token_address, + "name": "test_bond_1", + "symbol": "TEST-test", + "total_supply": 9999999, + "contact_information": "test1", + "privacy_policy": "test2", + "tradable_exchange_contract_address": "0x1234567890123456789012345678901234567890", + "status": False, + "personal_info_contract_address": "0x1234567890123456789012345678901234567891", + "require_personal_info_registered": True, + "transferable": True, + "is_offering": True, + "transfer_approval_required": True, + "face_value": 9999998, + "face_value_currency": "JPY", + "interest_rate": 99.999, + "interest_payment_date": [ + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + ], + "interest_payment_currency": "JPY", + "redemption_date": "99991231", + "redemption_value": 9999997, + "redemption_value_currency": "JPY", + "return_date": "99991230", + "return_amount": "return_amount-test", + "base_fx_rate": 123.456789, + "purpose": "purpose-test", + "memo": "memo-test", + "is_redeemed": True, + } + bond_1.__dict__ = token_attr mock_IbetStraightBondContract_get.side_effect = [bond_1] # request target api @@ -107,8 +150,9 @@ def test_normal_1_1(self, mock_IbetStraightBondContract_get, client, db): assert resp.json() == { "issuer_address": issuer_address, "token_address": token_address, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": token_attr, "balance": 10, "exchange_balance": 11, "exchange_commitment": 12, @@ -130,9 +174,9 @@ def test_normal_1_2(self, mock_IbetShareContract_get, client, db): _token = Token() _token.token_address = token_address _token.issuer_address = issuer_address - _token.type = TokenType.IBET_SHARE.value + _token.type = TokenType.IBET_SHARE _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -176,7 +220,31 @@ def test_normal_1_2(self, mock_IbetShareContract_get, client, db): # mock share_1 = IbetShareContract() - share_1.name = "test_share_1" + token_attr = { + "issuer_address": issuer_address, + "token_address": token_address, + "name": "test_share_1", + "symbol": "TEST-test", + "total_supply": 999999, + "contact_information": "test1", + "privacy_policy": "test2", + "tradable_exchange_contract_address": "0x1234567890123456789012345678901234567890", + "status": False, + "personal_info_contract_address": "0x1234567890123456789012345678901234567891", + "require_personal_info_registered": False, + "transferable": True, + "is_offering": True, + "transfer_approval_required": True, + "issue_price": 999997, + "cancellation_date": "99991231", + "memo": "memo_test", + "principal_value": 999998, + "is_canceled": True, + "dividends": 9.99, + "dividend_record_date": "99991230", + "dividend_payment_date": "99991229", + } + share_1.__dict__ = token_attr mock_IbetShareContract_get.side_effect = [share_1] # request target api @@ -192,8 +260,9 @@ def test_normal_1_2(self, mock_IbetShareContract_get, client, db): assert resp.json() == { "issuer_address": issuer_address, "token_address": token_address, - "token_type": TokenType.IBET_SHARE.value, + "token_type": TokenType.IBET_SHARE, "token_name": "test_share_1", + "token_attributes": token_attr, "balance": 10, "exchange_balance": 11, "exchange_commitment": 12, @@ -213,9 +282,9 @@ def test_normal_2(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = token_address _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -233,7 +302,50 @@ def test_normal_2(self, mock_IbetStraightBondContract_get, client, db): # mock bond_1 = IbetStraightBondContract() - bond_1.name = "test_bond_1" + token_attr = { + "issuer_address": issuer_address, + "token_address": token_address, + "name": "test_bond_1", + "symbol": "TEST-test", + "total_supply": 9999999, + "contact_information": "test1", + "privacy_policy": "test2", + "tradable_exchange_contract_address": "0x1234567890123456789012345678901234567890", + "status": False, + "personal_info_contract_address": "0x1234567890123456789012345678901234567891", + "require_personal_info_registered": True, + "transferable": True, + "is_offering": True, + "transfer_approval_required": True, + "face_value": 9999998, + "face_value_currency": "JPY", + "interest_rate": 99.999, + "interest_payment_date": [ + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + ], + "interest_payment_currency": "JPY", + "redemption_date": "99991231", + "redemption_value": 9999997, + "redemption_value_currency": "JPY", + "return_date": "99991230", + "return_amount": "return_amount-test", + "base_fx_rate": 123.456789, + "purpose": "purpose-test", + "memo": "memo-test", + "is_redeemed": True, + } + bond_1.__dict__ = token_attr mock_IbetStraightBondContract_get.side_effect = [bond_1] # request target api @@ -248,8 +360,9 @@ def test_normal_2(self, mock_IbetStraightBondContract_get, client, db): assert resp.json() == { "issuer_address": issuer_address, "token_address": token_address, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": token_attr, "balance": 0, "exchange_balance": 0, "exchange_commitment": 12, @@ -270,9 +383,9 @@ def test_normal_3_1(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = token_address _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -290,7 +403,50 @@ def test_normal_3_1(self, mock_IbetStraightBondContract_get, client, db): # mock bond_1 = IbetStraightBondContract() - bond_1.name = "test_bond_1" + token_attr = { + "issuer_address": issuer_address, + "token_address": token_address, + "name": "test_bond_1", + "symbol": "TEST-test", + "total_supply": 9999999, + "contact_information": "test1", + "privacy_policy": "test2", + "tradable_exchange_contract_address": "0x1234567890123456789012345678901234567890", + "status": False, + "personal_info_contract_address": "0x1234567890123456789012345678901234567891", + "require_personal_info_registered": True, + "transferable": True, + "is_offering": True, + "transfer_approval_required": True, + "face_value": 9999998, + "face_value_currency": "JPY", + "interest_rate": 99.999, + "interest_payment_date": [ + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + ], + "interest_payment_currency": "JPY", + "redemption_date": "99991231", + "redemption_value": 9999997, + "redemption_value_currency": "JPY", + "return_date": "99991230", + "return_amount": "return_amount-test", + "base_fx_rate": 123.456789, + "purpose": "purpose-test", + "memo": "memo-test", + "is_redeemed": True, + } + bond_1.__dict__ = token_attr mock_IbetStraightBondContract_get.side_effect = [bond_1] # request target api @@ -306,8 +462,9 @@ def test_normal_3_1(self, mock_IbetStraightBondContract_get, client, db): assert resp.json() == { "issuer_address": issuer_address, "token_address": token_address, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": token_attr, "balance": 0, "exchange_balance": 0, "exchange_commitment": 0, @@ -327,9 +484,9 @@ def test_normal_3_2(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = token_address _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -357,7 +514,50 @@ def test_normal_3_2(self, mock_IbetStraightBondContract_get, client, db): # mock bond_1 = IbetStraightBondContract() - bond_1.name = "test_bond_1" + token_attr = { + "issuer_address": issuer_address, + "token_address": token_address, + "name": "test_bond_1", + "symbol": "TEST-test", + "total_supply": 9999999, + "contact_information": "test1", + "privacy_policy": "test2", + "tradable_exchange_contract_address": "0x1234567890123456789012345678901234567890", + "status": False, + "personal_info_contract_address": "0x1234567890123456789012345678901234567891", + "require_personal_info_registered": True, + "transferable": True, + "is_offering": True, + "transfer_approval_required": True, + "face_value": 9999998, + "face_value_currency": "JPY", + "interest_rate": 99.999, + "interest_payment_date": [ + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + ], + "interest_payment_currency": "JPY", + "redemption_date": "99991231", + "redemption_value": 9999997, + "redemption_value_currency": "JPY", + "return_date": "99991230", + "return_amount": "return_amount-test", + "base_fx_rate": 123.456789, + "purpose": "purpose-test", + "memo": "memo-test", + "is_redeemed": True, + } + bond_1.__dict__ = token_attr mock_IbetStraightBondContract_get.side_effect = [bond_1] # request target api @@ -373,8 +573,9 @@ def test_normal_3_2(self, mock_IbetStraightBondContract_get, client, db): assert resp.json() == { "issuer_address": issuer_address, "token_address": token_address, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": token_attr, "balance": 0, "exchange_balance": 0, "exchange_commitment": 0, @@ -395,9 +596,9 @@ def test_normal_3_3(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = token_address _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -415,7 +616,50 @@ def test_normal_3_3(self, mock_IbetStraightBondContract_get, client, db): # mock bond_1 = IbetStraightBondContract() - bond_1.name = "test_bond_1" + token_attr = { + "issuer_address": issuer_address, + "token_address": token_address, + "name": "test_bond_1", + "symbol": "TEST-test", + "total_supply": 9999999, + "contact_information": "test1", + "privacy_policy": "test2", + "tradable_exchange_contract_address": "0x1234567890123456789012345678901234567890", + "status": False, + "personal_info_contract_address": "0x1234567890123456789012345678901234567891", + "require_personal_info_registered": True, + "transferable": True, + "is_offering": True, + "transfer_approval_required": True, + "face_value": 9999998, + "face_value_currency": "JPY", + "interest_rate": 99.999, + "interest_payment_date": [ + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + ], + "interest_payment_currency": "JPY", + "redemption_date": "99991231", + "redemption_value": 9999997, + "redemption_value_currency": "JPY", + "return_date": "99991230", + "return_amount": "return_amount-test", + "base_fx_rate": 123.456789, + "purpose": "purpose-test", + "memo": "memo-test", + "is_redeemed": True, + } + bond_1.__dict__ = token_attr mock_IbetStraightBondContract_get.side_effect = [bond_1] # request target api @@ -431,8 +675,9 @@ def test_normal_3_3(self, mock_IbetStraightBondContract_get, client, db): assert resp.json() == { "issuer_address": issuer_address, "token_address": token_address, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": token_attr, "balance": 5, "exchange_balance": 10, "exchange_commitment": 15, @@ -452,9 +697,9 @@ def test_normal_3_4(self, mock_IbetStraightBondContract_get, client, db): _token = Token() _token.token_address = token_address _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -482,7 +727,50 @@ def test_normal_3_4(self, mock_IbetStraightBondContract_get, client, db): # mock bond_1 = IbetStraightBondContract() - bond_1.name = "test_bond_1" + token_attr = { + "issuer_address": issuer_address, + "token_address": token_address, + "name": "test_bond_1", + "symbol": "TEST-test", + "total_supply": 9999999, + "contact_information": "test1", + "privacy_policy": "test2", + "tradable_exchange_contract_address": "0x1234567890123456789012345678901234567890", + "status": False, + "personal_info_contract_address": "0x1234567890123456789012345678901234567891", + "require_personal_info_registered": True, + "transferable": True, + "is_offering": True, + "transfer_approval_required": True, + "face_value": 9999998, + "face_value_currency": "JPY", + "interest_rate": 99.999, + "interest_payment_date": [ + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + "99991231", + ], + "interest_payment_currency": "JPY", + "redemption_date": "99991231", + "redemption_value": 9999997, + "redemption_value_currency": "JPY", + "return_date": "99991230", + "return_amount": "return_amount-test", + "base_fx_rate": 123.456789, + "purpose": "purpose-test", + "memo": "memo-test", + "is_redeemed": True, + } + bond_1.__dict__ = token_attr mock_IbetStraightBondContract_get.side_effect = [bond_1] # request target api @@ -498,8 +786,9 @@ def test_normal_3_4(self, mock_IbetStraightBondContract_get, client, db): assert resp.json() == { "issuer_address": issuer_address, "token_address": token_address, - "token_type": TokenType.IBET_STRAIGHT_BOND.value, + "token_type": TokenType.IBET_STRAIGHT_BOND, "token_name": "test_bond_1", + "token_attributes": token_attr, "balance": 5, "exchange_balance": 10, "exchange_commitment": 15, @@ -575,9 +864,9 @@ def test_error_2_2(self, client, db): _token.issuer_address = ( "0x1234567890123456789012345678900000000101" # not target ) - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.version = TokenVersion.V_24_09 db.add(_token) @@ -619,9 +908,9 @@ def test_error_3(self, client, db): _token = Token() _token.token_address = token_address _token.issuer_address = issuer_address - _token.type = TokenType.IBET_STRAIGHT_BOND.value + _token.type = TokenType.IBET_STRAIGHT_BOND _token.tx_hash = "" - _token.abi = "" + _token.abi = {} _token.token_status = 0 _token.version = TokenVersion.V_24_09 db.add(_token)