From ef38a5a9587c82c5b2d2ba928a7670d179ffe32e Mon Sep 17 00:00:00 2001 From: Rui Date: Thu, 29 Aug 2024 21:48:53 +0800 Subject: [PATCH] TransferRequiredInputTests --- .../state/model/TradingStateMachine.kt | 43 ++-- .../transfer/TransferFieldsValidator.kt | 14 +- .../transfer/TransferOutValidator.kt | 20 +- .../validation/TransferRequiredInputTests.kt | 215 +++++++++++++----- 4 files changed, 213 insertions(+), 79 deletions(-) diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt index c8fc065e5..f444f52c5 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt @@ -1008,28 +1008,29 @@ open class TradingStateMachine( price = null, // priceOverwrite(markets), configs = null, // This is used to get the IMF.. with "null" the default value 0.05 will be used ) - } - this.marketsSummary?.let { marketsSummary -> - val periods = if (this.input != null) { - setOf( - CalculationPeriod.current, - CalculationPeriod.post, - CalculationPeriod.settled, - ) - } else { - setOf(CalculationPeriod.current) - } + } else { + this.marketsSummary?.let { marketsSummary -> + val periods = if (this.input != null) { + setOf( + CalculationPeriod.current, + CalculationPeriod.post, + CalculationPeriod.settled, + ) + } else { + setOf(CalculationPeriod.current) + } - parser.asNativeMap(marketsSummary["markets"])?.let { markets -> - val modifiedAccount = accountCalculator.calculate( - account = account, - subaccountNumbers = subaccountNumbers, - configs = null, - markets = markets, - price = priceOverwrite(markets), - periods = periods, - ) - this.account = modifiedAccount + parser.asNativeMap(marketsSummary["markets"])?.let { markets -> + val modifiedAccount = accountCalculator.calculate( + account = account, + subaccountNumbers = subaccountNumbers, + configs = null, + markets = markets, + price = priceOverwrite(markets), + periods = periods, + ) + this.account = modifiedAccount + } } } } diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/validator/transfer/TransferFieldsValidator.kt b/src/commonMain/kotlin/exchange.dydx.abacus/validator/transfer/TransferFieldsValidator.kt index 992fec6bd..916448db7 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/validator/transfer/TransferFieldsValidator.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/validator/transfer/TransferFieldsValidator.kt @@ -26,7 +26,19 @@ internal class TransferFieldsValidator( val transfer = internalState.input.transfer val type = transfer.type ?: return null when (type) { - TransferType.deposit, TransferType.withdrawal -> { + TransferType.deposit -> { + val usdcSize = parser.asDouble(transfer.size?.usdcSize) ?: 0.0 + if (usdcSize <= 0.0) { + errors.add( + required( + errorCode = "REQUIRED_SIZE", + field = "size.usdcSize", + actionStringKey = "APP.TRADE.ENTER_AMOUNT", + ), + ) + } + } + TransferType.withdrawal -> { val usdcSize = parser.asDouble(transfer.size?.usdcSize) ?: 0.0 if (usdcSize <= 0.0) { errors.add( diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/validator/transfer/TransferOutValidator.kt b/src/commonMain/kotlin/exchange.dydx.abacus/validator/transfer/TransferOutValidator.kt index 87b9f8164..5200bd803 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/validator/transfer/TransferOutValidator.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/validator/transfer/TransferOutValidator.kt @@ -1,5 +1,7 @@ package exchange.dydx.abacus.validator.transfer +import exchange.dydx.abacus.output.input.ErrorType +import exchange.dydx.abacus.output.input.TransferType import exchange.dydx.abacus.output.input.ValidationError import exchange.dydx.abacus.protocols.LocalizerProtocol import exchange.dydx.abacus.protocols.ParserProtocol @@ -22,7 +24,23 @@ internal class TransferOutValidator( restricted: Boolean, environment: V4Environment? ): List? { - return null + val transfer = internalState.input.transfer ?: return null + val address = transfer.address + val type = transfer.type + if (type == TransferType.transferOut && !address.isNullOrEmpty() && !address.isAddressValid()) { + return listOf( + error( + type = ErrorType.error, + errorCode = "INVALID_ADDRESS", + fields = listOf("address"), + actionStringKey = "APP.DIRECT_TRANSFER_MODAL.ADDRESS_FIELD", + titleStringKey = "APP.DIRECT_TRANSFER_MODAL.INVALID_ADDRESS_TITLE", + textStringKey = "APP.DIRECT_TRANSFER_MODAL.INVALID_ADDRESS_BODY", + ), + ) + } else { + return null + } } override fun validateTransferDeprecated( diff --git a/src/commonTest/kotlin/exchange.dydx.abacus/validation/TransferRequiredInputTests.kt b/src/commonTest/kotlin/exchange.dydx.abacus/validation/TransferRequiredInputTests.kt index d2cf02cc2..e3a30f892 100644 --- a/src/commonTest/kotlin/exchange.dydx.abacus/validation/TransferRequiredInputTests.kt +++ b/src/commonTest/kotlin/exchange.dydx.abacus/validation/TransferRequiredInputTests.kt @@ -1,11 +1,15 @@ package exchange.dydx.abacus.validation +import exchange.dydx.abacus.output.input.ErrorType +import exchange.dydx.abacus.output.input.TransferType import exchange.dydx.abacus.payload.v4.V4BaseTests import exchange.dydx.abacus.state.model.TransferInputField import exchange.dydx.abacus.state.model.transfer import exchange.dydx.abacus.tests.extensions.log import exchange.dydx.abacus.utils.ServerTime import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull class TransferRequiredInputTests : V4BaseTests() { @Test @@ -40,11 +44,23 @@ class TransferRequiredInputTests : V4BaseTests() { } private fun testTransferInputDeposit() { - test( - { - perp.transfer("DEPOSIT", TransferInputField.type, environment = mock.v4Environment) - }, - """ + if (perp.staticTyping) { + perp.transfer("DEPOSIT", TransferInputField.type, environment = mock.v4Environment) + + val transfer = perp.internalState.input.transfer + assertEquals(TransferType.deposit, transfer.type) + + val error = perp.internalState.input.errors?.firstOrNull() + assertEquals("REQUIRED_SIZE", error?.code) + assertEquals(ErrorType.required, error?.type) + assertEquals("size.usdcSize", error?.fields?.first()) + assertEquals("APP.TRADE.ENTER_AMOUNT", error?.resources?.action?.stringKey) + } else { + test( + { + perp.transfer("DEPOSIT", TransferInputField.type, environment = mock.v4Environment) + }, + """ { "input": { "current": "transfer", @@ -67,14 +83,24 @@ class TransferRequiredInputTests : V4BaseTests() { ] } } - """.trimIndent(), - ) + """.trimIndent(), + ) + } + + if (perp.staticTyping) { + perp.transfer("1.0", TransferInputField.usdcSize, environment = mock.v4Environment) - test( - { - perp.transfer("1.0", TransferInputField.usdcSize, environment = mock.v4Environment) - }, - """ + val transfer = perp.internalState.input.transfer + assertEquals(TransferType.deposit, transfer.type) + + val error = perp.internalState.input.errors?.firstOrNull() + assertEquals(null, error) + } else { + test( + { + perp.transfer("1.0", TransferInputField.usdcSize, environment = mock.v4Environment) + }, + """ { "input": { "current": "transfer", @@ -84,16 +110,33 @@ class TransferRequiredInputTests : V4BaseTests() { "errors": null } } - """.trimIndent(), - ) + """.trimIndent(), + ) + } } private fun testTransferInputWithdraw() { - test( - { - perp.transfer("WITHDRAWAL", TransferInputField.type, environment = mock.v4Environment) - }, - """ + if (perp.staticTyping) { + perp.transfer("WITHDRAWAL", TransferInputField.type, environment = mock.v4Environment) + + val transfer = perp.internalState.input.transfer + assertEquals(TransferType.withdrawal, transfer.type) + + val error = perp.internalState.input.errors?.firstOrNull() + assertEquals("REQUIRED_SIZE", error?.code) + assertEquals(ErrorType.required, error?.type) + assertEquals("size.usdcSize", error?.fields?.first()) + assertEquals("APP.TRADE.ENTER_AMOUNT", error?.resources?.action?.stringKey) + } else { + test( + { + perp.transfer( + "WITHDRAWAL", + TransferInputField.type, + environment = mock.v4Environment, + ) + }, + """ { "input": { "current": "transfer", @@ -116,14 +159,28 @@ class TransferRequiredInputTests : V4BaseTests() { ] } } - """.trimIndent(), - ) + """.trimIndent(), + ) + } + + if (perp.staticTyping) { + perp.transfer("1.0", TransferInputField.usdcSize, environment = mock.v4Environment) - test( - { - perp.transfer("1.0", TransferInputField.usdcSize, environment = mock.v4Environment) - }, - """ + val transfer = perp.internalState.input.transfer + assertEquals(TransferType.withdrawal, transfer.type) + + val error = perp.internalState.input.errors?.firstOrNull() + assertEquals("REQUIRED_ADDRESS", error?.code) + assertEquals(ErrorType.required, error?.type) + + perp.transfer("dydx16zfx8g4jg9vels3rsvcym490tkn5la304c57e9", TransferInputField.address, environment = mock.v4Environment) + assertNull(perp.internalState.input.errors?.firstOrNull()) + } else { + test( + { + perp.transfer("1.0", TransferInputField.usdcSize, environment = mock.v4Environment) + }, + """ { "input": { "current": "transfer", @@ -133,16 +190,29 @@ class TransferRequiredInputTests : V4BaseTests() { "errors": null } } - """.trimIndent(), - ) + """.trimIndent(), + ) + } } private fun testTransferInputTransferOut() { - test( - { - perp.transfer("TRANSFER_OUT", TransferInputField.type, environment = mock.v4Environment) - }, - """ + if (perp.staticTyping) { + perp.transfer("TRANSFER_OUT", TransferInputField.type, environment = mock.v4Environment) + + val transfer = perp.internalState.input.transfer + assertEquals(TransferType.transferOut, transfer.type) + + val error = perp.internalState.input.errors?.firstOrNull() + assertEquals("REQUIRED_ADDRESS", error?.code) + assertEquals(ErrorType.required, error?.type) + assertEquals("address", error?.fields?.first()) + assertEquals("APP.DIRECT_TRANSFER_MODAL.ENTER_ETH_ADDRESS", error?.resources?.action?.stringKey) + } else { + test( + { + perp.transfer("TRANSFER_OUT", TransferInputField.type, environment = mock.v4Environment) + }, + """ { "input": { "current": "transfer", @@ -165,14 +235,24 @@ class TransferRequiredInputTests : V4BaseTests() { ] } } - """.trimIndent(), - ) + """.trimIndent(), + ) + } - test( - { - perp.transfer("1.0", TransferInputField.usdcSize, environment = mock.v4Environment) - }, - """ + if (perp.staticTyping) { + perp.transfer("1.0", TransferInputField.usdcSize, environment = mock.v4Environment) + + val transfer = perp.internalState.input.transfer + assertEquals(TransferType.transferOut, transfer.type) + + val error = perp.internalState.input.errors?.firstOrNull() + assertEquals("REQUIRED_ADDRESS", error?.code) + } else { + test( + { + perp.transfer("1.0", TransferInputField.usdcSize, environment = mock.v4Environment) + }, + """ { "input": { "current": "transfer", @@ -195,14 +275,27 @@ class TransferRequiredInputTests : V4BaseTests() { ] } } - """.trimIndent(), - ) + """.trimIndent(), + ) + } - test( - { - perp.transfer("dydx1111111", TransferInputField.address, environment = mock.v4Environment) - }, - """ + if (perp.staticTyping) { + perp.transfer("dydx1111111", TransferInputField.address, environment = mock.v4Environment) + + val transfer = perp.internalState.input.transfer + assertEquals(TransferType.transferOut, transfer.type) + + val error = perp.internalState.input.errors?.firstOrNull() + assertEquals("INVALID_ADDRESS", error?.code) + assertEquals(ErrorType.error, error?.type) + assertEquals("address", error?.fields?.first()) + assertEquals("APP.DIRECT_TRANSFER_MODAL.ADDRESS_FIELD", error?.resources?.action?.stringKey) + } else { + test( + { + perp.transfer("dydx1111111", TransferInputField.address, environment = mock.v4Environment) + }, + """ { "input": { "current": "transfer", @@ -224,14 +317,23 @@ class TransferRequiredInputTests : V4BaseTests() { ] } } - """.trimIndent(), - ) + """.trimIndent(), + ) + } - test( - { - perp.transfer("dydx16zfx8g4jg9vels3rsvcym490tkn5la304c57e9", TransferInputField.address, environment = mock.v4Environment) - }, - """ + if (perp.staticTyping) { + perp.transfer("dydx16zfx8g4jg9vels3rsvcym490tkn5la304c57e9", TransferInputField.address, environment = mock.v4Environment) + + val transfer = perp.internalState.input.transfer + assertEquals(TransferType.transferOut, transfer.type) + + assertNull(perp.internalState.input.errors?.firstOrNull()) + } else { + test( + { + perp.transfer("dydx16zfx8g4jg9vels3rsvcym490tkn5la304c57e9", TransferInputField.address, environment = mock.v4Environment) + }, + """ { "input": { "current": "transfer", @@ -241,7 +343,8 @@ class TransferRequiredInputTests : V4BaseTests() { "errors": null } } - """.trimIndent(), - ) + """.trimIndent(), + ) + } } }