diff --git a/accounts-test-data/.gitignore b/accounts-journey-fake/.gitignore similarity index 100% rename from accounts-test-data/.gitignore rename to accounts-journey-fake/.gitignore diff --git a/accounts-test-data/build.gradle.kts b/accounts-journey-fake/build.gradle.kts similarity index 100% rename from accounts-test-data/build.gradle.kts rename to accounts-journey-fake/build.gradle.kts diff --git a/accounts-test-data/proguard-rules.pro b/accounts-journey-fake/proguard-rules.pro similarity index 100% rename from accounts-test-data/proguard-rules.pro rename to accounts-journey-fake/proguard-rules.pro diff --git a/accounts-journey-fake/src/main/kotlin/com/backbase/accounts_journey/generator/AccountDetailGenerator.kt b/accounts-journey-fake/src/main/kotlin/com/backbase/accounts_journey/generator/AccountDetailGenerator.kt new file mode 100644 index 00000000..cee838f6 --- /dev/null +++ b/accounts-journey-fake/src/main/kotlin/com/backbase/accounts_journey/generator/AccountDetailGenerator.kt @@ -0,0 +1,115 @@ +package com.backbase.accounts_journey.generator + +import com.backbase.accounts_journey.domain.model.account_detail.AccountDetail +import com.backbase.accounts_journey.domain.model.account_detail.AccountUserPreferences +import com.backbase.accounts_journey.domain.model.account_detail.ExternalProductItem +import com.backbase.accounts_journey.domain.model.common.DebitCardItem +import com.backbase.accounts_journey.domain.model.common.ProductState +import com.backbase.accounts_journey.domain.model.common.TimeUnit +import com.backbase.android.test_data.StringGenerator +import java.math.BigDecimal +import java.math.RoundingMode +import java.time.LocalDate +import java.time.OffsetDateTime +import kotlin.random.Random + +/** + * A random AccountDetail generator. It is not fully implemented, but it gives you an idea how to randomize the data. + */ +@Suppress("MaximumLineLength", "LongMethod", "MaxLineLength") +object AccountDetailGenerator { + + fun randomAccountDetailBuilder(overrideBlock: (AccountDetail.Builder.() -> Unit)? = null) = AccountDetail.Builder().apply { + // Required fields + id = StringGenerator.randomString() + productId = StringGenerator.randomString() + currency = StringGenerator.generateRandomCurrency() + + // Optional fields + productKindName = StringGenerator.randomString() + legalEntityIds = setOf(StringGenerator.randomString(), StringGenerator.randomString()) + productTypeName = listOf("Savings", "Checking", "Credit", "Investment").random() + externalProductId = StringGenerator.randomString() + externalArrangementId = StringGenerator.randomString() + userPreferences = AccountUserPreferences { arrangementId = StringGenerator.randomString() } + product = ExternalProductItem {} + state = ProductState {} + parentId = StringGenerator.randomString() + name = "Account ${StringGenerator.randomString()}" + bookedBalance = BigDecimal(Random.nextDouble(1000.0, 100000.0)).setScale(2, RoundingMode.HALF_UP) + availableBalance = BigDecimal(Random.nextDouble(500.0, 95000.0)).setScale(2, RoundingMode.HALF_UP) + creditLimit = BigDecimal(Random.nextDouble(1000.0, 50000.0)).setScale(2, RoundingMode.HALF_UP) + IBAN = "GB${Random.nextInt(10, 99)}${StringGenerator.randomString()}${Random.nextLong(10000000, 99999999)}" + BBAN = StringGenerator.randomString() + BIC = "${StringGenerator.randomString()}${StringGenerator.randomString()}${StringGenerator.randomString()}" + externalTransferAllowed = Random.nextBoolean() + urgentTransferAllowed = Random.nextBoolean() + accruedInterest = BigDecimal(Random.nextDouble(0.0, 1000.0)).setScale(2, RoundingMode.HALF_UP) + number = Random.nextLong(1000000000, 9999999999).toString() + principalAmount = BigDecimal(Random.nextDouble(10000.0, 500000.0)).setScale(2, RoundingMode.HALF_UP) + currentInvestmentValue = BigDecimal(Random.nextDouble(5000.0, 100000.0)).setScale(2, RoundingMode.HALF_UP) + productNumber = Random.nextLong(100000, 999999).toString() + bankBranchCode = Random.nextInt(1000, 9999).toString() + bankBranchCode2 = Random.nextInt(100, 999).toString() + accountOpeningDate = OffsetDateTime.now().minusDays(Random.nextLong(30, 3650)) + accountInterestRate = BigDecimal(Random.nextDouble(0.1, 5.0)).setScale(3, RoundingMode.HALF_UP) + valueDateBalance = BigDecimal(Random.nextDouble(1000.0, 95000.0)).setScale(2, RoundingMode.HALF_UP) + creditLimitUsage = BigDecimal(Random.nextDouble(0.0, 10000.0)).setScale(2, RoundingMode.HALF_UP) + creditLimitInterestRate = BigDecimal(Random.nextDouble(5.0, 25.0)).setScale(3, RoundingMode.HALF_UP) + creditLimitExpiryDate = OffsetDateTime.now().plusYears(Random.nextLong(1, 5)) + startDate = OffsetDateTime.now().minusDays(Random.nextLong(30, 1000)) + termUnit = TimeUnit.entries.toTypedArray().random() + termNumber = BigDecimal(Random.nextInt(1, 60)) + interestPaymentFrequencyUnit = TimeUnit.entries.toTypedArray().random() + interestPaymentFrequencyNumber = BigDecimal(Random.nextInt(1, 12)) + maturityDate = OffsetDateTime.now().plusYears(Random.nextLong(1, 10)) + maturityAmount = BigDecimal(Random.nextDouble(10000.0, 200000.0)).setScale(2, RoundingMode.HALF_UP) + autoRenewalIndicator = Random.nextBoolean() + interestSettlementAccount = StringGenerator.randomString() + outstandingPrincipalAmount = BigDecimal(Random.nextDouble(5000.0, 100000.0)).setScale(2, RoundingMode.HALF_UP) + monthlyInstalmentAmount = BigDecimal(Random.nextDouble(100.0, 2000.0)).setScale(2, RoundingMode.HALF_UP) + amountInArrear = BigDecimal(Random.nextDouble(0.0, 500.0)).setScale(2, RoundingMode.HALF_UP) + minimumRequiredBalance = BigDecimal(Random.nextDouble(0.0, 1000.0)).setScale(2, RoundingMode.HALF_UP) + creditCardAccountNumber = Random.nextLong(1000000000000000, 9999999999999999).toString() + validThru = OffsetDateTime.now().plusYears(Random.nextLong(1, 5)) + applicableInterestRate = BigDecimal(Random.nextDouble(0.5, 15.0)).setScale(3, RoundingMode.HALF_UP) + remainingCredit = BigDecimal(Random.nextDouble(1000.0, 40000.0)).setScale(2, RoundingMode.HALF_UP) + outstandingPayment = BigDecimal(Random.nextDouble(0.0, 5000.0)).setScale(2, RoundingMode.HALF_UP) + minimumPayment = BigDecimal(Random.nextDouble(25.0, 500.0)).setScale(2, RoundingMode.HALF_UP) + minimumPaymentDueDate = OffsetDateTime.now().plusDays(Random.nextLong(1, 30)) + totalInvestmentValue = BigDecimal(Random.nextDouble(10000.0, 500000.0)).setScale(2, RoundingMode.HALF_UP) + debitCards = setOf(DebitCardItem { }) + accountHolderAddressLine1 = "${Random.nextInt(1, 999)} ${listOf("Main", "Oak", "Elm", "Pine", "First").random()} Street" + accountHolderAddressLine2 = if (Random.nextBoolean()) "Apt ${Random.nextInt(1, 999)}" else null + accountHolderStreetName = listOf("Main Street", "Oak Avenue", "Elm Drive", "Pine Road").random() + town = listOf("New York", "Los Angeles", "Chicago", "Houston", "Phoenix").random() + postCode = Random.nextInt(10000, 99999).toString() + countrySubDivision = listOf("NY", "CA", "IL", "TX", "AZ").random() + accountHolderNames = "${listOf("John", "Jane", "Michael", "Sarah", "David").random()} ${listOf("Smith", "Johnson", "Williams", "Brown", "Jones").random()}" + accountHolderCountry = listOf("US", "GB", "DE", "FR", "NL").random() + creditAccount = Random.nextBoolean() + debitAccount = Random.nextBoolean() + lastUpdateDate = OffsetDateTime.now().minusDays(Random.nextLong(0, 30)) + bankAlias = "Bank ${StringGenerator.randomString()}" + sourceId = StringGenerator.randomString() + externalStateId = StringGenerator.randomString() + externalParentId = StringGenerator.randomString() + financialInstitutionId = Random.nextLong(1000, 9999) + lastSyncDate = OffsetDateTime.now().minusHours(Random.nextLong(1, 48)) + additions = mapOf( + "customField1" to StringGenerator.randomString(), + "customField2" to StringGenerator.randomString() + ) + unmaskableAttributes = null // Complex type - keeping null for now + displayName = "Display ${StringGenerator.randomString()}" + cardDetails = null // Complex type - keeping null for now + interestDetails = null // Complex type - keeping null for now + reservedAmount = BigDecimal(Random.nextDouble(0.0, 1000.0)).setScale(2, RoundingMode.HALF_UP) + remainingPeriodicTransfers = BigDecimal(Random.nextInt(0, 10)) + nextClosingDate = LocalDate.now().plusDays(Random.nextLong(1, 30)) + overdueSince = if (Random.nextBoolean()) LocalDate.now().minusDays(Random.nextLong(1, 60)) else null + externalAccountStatus = listOf("ACTIVE", "INACTIVE", "PENDING", "CLOSED").random() + + overrideBlock?.let { this.it() } + } +} diff --git a/accounts-journey-fake/src/main/kotlin/com/backbase/accounts_journey/generator/AccountSummaryGenerator.kt b/accounts-journey-fake/src/main/kotlin/com/backbase/accounts_journey/generator/AccountSummaryGenerator.kt new file mode 100644 index 00000000..1e736e72 --- /dev/null +++ b/accounts-journey-fake/src/main/kotlin/com/backbase/accounts_journey/generator/AccountSummaryGenerator.kt @@ -0,0 +1,390 @@ +package com.backbase.accounts_journey.generator + +import com.backbase.accounts_journey.domain.model.account_summary.AccountSummary +import com.backbase.accounts_journey.domain.model.account_summary.MaskableAttribute +import com.backbase.accounts_journey.domain.model.account_summary.UserPreferences +import com.backbase.accounts_journey.domain.model.account_summary.credit_card.CreditCard +import com.backbase.accounts_journey.domain.model.account_summary.credit_card.CreditCards +import com.backbase.accounts_journey.domain.model.account_summary.current_accounts.CurrentAccount +import com.backbase.accounts_journey.domain.model.account_summary.current_accounts.CurrentAccounts +import com.backbase.accounts_journey.domain.model.account_summary.custom_products.CustomProducts +import com.backbase.accounts_journey.domain.model.account_summary.custom_products.GeneralAccount +import com.backbase.accounts_journey.domain.model.account_summary.debit_card.DebitCard +import com.backbase.accounts_journey.domain.model.account_summary.debit_card.DebitCards +import com.backbase.accounts_journey.domain.model.account_summary.investment_accounts.InvestmentAccount +import com.backbase.accounts_journey.domain.model.account_summary.investment_accounts.InvestmentAccounts +import com.backbase.accounts_journey.domain.model.account_summary.loan.Loan +import com.backbase.accounts_journey.domain.model.account_summary.loan.Loans +import com.backbase.accounts_journey.domain.model.account_summary.savings_accounts.SavingsAccount +import com.backbase.accounts_journey.domain.model.account_summary.savings_accounts.SavingsAccounts +import com.backbase.accounts_journey.domain.model.account_summary.term_deposits.TermDeposit +import com.backbase.accounts_journey.domain.model.account_summary.term_deposits.TermDeposits +import com.backbase.accounts_journey.domain.model.common.AggregatedBalance +import com.backbase.accounts_journey.domain.model.common.ProductState +import com.backbase.android.test_data.StringGenerator.generateRandomBBAN +import com.backbase.android.test_data.StringGenerator.generateRandomBIC +import com.backbase.android.test_data.StringGenerator.generateRandomCurrency +import com.backbase.android.test_data.StringGenerator.randomString +import java.math.BigDecimal +import java.math.RoundingMode +import java.time.OffsetDateTime +import kotlin.random.Random + +/** + * A random AccountSummary generator. It is not fully implemented, but it gives you an idea how to randomize the data. + */ +@Suppress("MaximumLineLength") +object AccountSummaryGenerator { + + fun randomAccountSummaryBuilder(overrideBlock: (AccountSummary.Builder.() -> Unit)? = null) = AccountSummary.Builder().apply { + // Custom products + customProducts = listOf(randomCustomProducts().build()) + + // Aggregated balance + aggregatedBalance = randomAggregatedBalance().build() + + // Current accounts + currentAccounts = randomCurrentAccounts().build() + + // Savings accounts + savingsAccounts = randomSavingsAccounts().build() + + // Credit cards + creditCards = randomCreditCards().build() + + // Loans + loans = randomLoans().build() + + // Term deposits + termDeposits = randomTermDeposits().build() + + // Debit cards + debitCards = randomDebitCards().build() + + // Investment accounts + investmentAccounts = randomInvestmentAccounts().build() + + // Additions + additions = randomAdditions() + + overrideBlock?.let { this.it() } + } + + fun randomCurrentAccounts(overrideBlock: (CurrentAccounts.Builder.() -> Unit)? = null) = CurrentAccounts.Builder().apply { + products = (1..Random.nextInt(1, 4)).map { + randomCurrentAccount().build() + } + name = "Current Accounts" + + overrideBlock?.let { this.it() } + } + + fun randomCurrentAccount(overrideBlock: (CurrentAccount.Builder.() -> Unit)? = null) = CurrentAccount.Builder().apply { + val randomNumber = Random.nextInt(1, 1000) + + debitCardItems = emptySet() + id = randomString() + name = "Current Account $randomNumber" + displayName = "My Current Account $randomNumber" + bookedBalance = BigDecimal(Random.nextDouble(1000.0, 50000.0)).setScale(2, RoundingMode.HALF_UP).toString() + availableBalance = BigDecimal(Random.nextDouble(1000.0, 50000.0)).setScale(2, RoundingMode.HALF_UP).toString() + creditLimit = BigDecimal(Random.nextDouble(1000.0, 10000.0)).setScale(2, RoundingMode.HALF_UP).toString() + currency = generateRandomCurrency() + BBAN = generateRandomBBAN() + BIC = generateRandomBIC() + unMaskableAttributes = setOf(MaskableAttribute.BBAN) + bankBranchCode = Random.nextInt(10000, 99999).toString() + accountInterestRate = BigDecimal(Random.nextDouble(0.1, 2.0)).setScale(3, RoundingMode.HALF_UP) + creditLimitUsage = BigDecimal(Random.nextDouble(0.0, 1000.0)).setScale(2, RoundingMode.HALF_UP) + creditLimitInterestRate = BigDecimal(Random.nextDouble(5.0, 15.0)).setScale(3, RoundingMode.HALF_UP) + creditLimitExpiryDate = OffsetDateTime.now().plusYears(Random.nextLong(1, 3)) + accruedInterest = BigDecimal(Random.nextDouble(0.0, 100.0)).setScale(2, RoundingMode.HALF_UP) + accountHolderNames = "${listOf("John", "Jane", "Michael", "Sarah").random()} ${listOf("Smith", "Johnson", "Williams", "Brown").random()}" + startDate = OffsetDateTime.now().minusDays(Random.nextLong(30, 1000)) + creditAccount = Random.nextBoolean() + debitAccount = Random.nextBoolean() + externalTransferAllowed = Random.nextBoolean() + crossCurrencyAllowed = Random.nextBoolean() + productKindName = "Current Account" + productTypeName = "Current Account" + bankAlias = "Current Account $randomNumber" + accountOpeningDate = OffsetDateTime.now().minusDays(Random.nextLong(30, 1000)) + lastUpdateDate = OffsetDateTime.now().minusDays(Random.nextLong(0, 30)) + userPreferences = UserPreferences { + alias = "My Current Account $randomNumber" + visible = true + favorite = Random.nextBoolean() + } + state = ProductState { + externalStateId = "Active" + state = "Active" + } + + overrideBlock?.let { this.it() } + } + + fun randomCustomProducts(overrideBlock: (CustomProducts.Builder.() -> Unit)? = null) = CustomProducts.Builder().apply { + id = Random.nextInt(1, 1000) + products = listOf(randomGeneralAccount().build()) + name = "Custom Products" + + overrideBlock?.let { this.it() } + } + + fun randomGeneralAccount(overrideBlock: (GeneralAccount.Builder.() -> Unit)? = null) = GeneralAccount.Builder().apply { + debitCardItems = emptySet() + id = randomString() + name = "Custom Product ${randomString()}" + displayName = "My Custom Product" + productTypeName = "Custom" + currency = generateRandomCurrency() + bookedBalance = BigDecimal(Random.nextDouble(1000.0, 50000.0)).setScale(2, RoundingMode.HALF_UP).toString() + availableBalance = BigDecimal(Random.nextDouble(1000.0, 50000.0)).setScale(2, RoundingMode.HALF_UP).toString() + accountHolderNames = "${listOf("John", "Jane", "Michael", "Sarah").random()} ${listOf("Smith", "Johnson", "Williams", "Brown").random()}" + state = ProductState { + externalStateId = "Active" + state = "Active" + } + userPreferences = UserPreferences { + alias = "My Custom Product" + visible = true + favorite = Random.nextBoolean() + } + + overrideBlock?.let { this.it() } + } + + fun randomAggregatedBalance(overrideBlock: (AggregatedBalance.Builder.() -> Unit)? = null) = AggregatedBalance.Builder().apply { + currency = generateRandomCurrency() + value = BigDecimal(Random.nextDouble(50000.0, 500000.0)).setScale(2, RoundingMode.HALF_UP).toString() + + overrideBlock?.let { this.it() } + } + + fun randomSavingsAccounts(overrideBlock: (SavingsAccounts.Builder.() -> Unit)? = null) = SavingsAccounts.Builder().apply { + products = (1..Random.nextInt(1, 3)).map { + randomSavingsAccount().build() + } + name = "Savings Accounts" + + overrideBlock?.let { this.it() } + } + + fun randomSavingsAccount(overrideBlock: (SavingsAccount.Builder.() -> Unit)? = null) = SavingsAccount.Builder().apply { + val randomNumber = Random.nextInt(1, 1000) + + id = randomString() + name = "Savings Account $randomNumber" + displayName = "My Savings Account $randomNumber" + bookedBalance = BigDecimal(Random.nextDouble(5000.0, 100000.0)).setScale(2, RoundingMode.HALF_UP).toString() + availableBalance = BigDecimal(Random.nextDouble(5000.0, 100000.0)).setScale(2, RoundingMode.HALF_UP).toString() + currency = generateRandomCurrency() + BBAN = generateRandomBBAN() + BIC = generateRandomBIC() + accountInterestRate = BigDecimal(Random.nextDouble(0.5, 4.0)).setScale(3, RoundingMode.HALF_UP) + accountHolderNames = "${listOf("John", "Jane", "Michael", "Sarah").random()} ${listOf("Smith", "Johnson", "Williams", "Brown").random()}" + productTypeName = "Savings Account" + bankAlias = "Savings Account $randomNumber" + accountOpeningDate = OffsetDateTime.now().minusDays(Random.nextLong(30, 1000)) + lastUpdateDate = OffsetDateTime.now().minusDays(Random.nextLong(0, 30)) + state = ProductState { + externalStateId = "Active" + state = "Active" + } + userPreferences = UserPreferences { + alias = "My Savings Account $randomNumber" + visible = true + favorite = Random.nextBoolean() + } + + overrideBlock?.let { this.it() } + } + + fun randomCreditCards(overrideBlock: (CreditCards.Builder.() -> Unit)? = null) = CreditCards.Builder().apply { + products = (1..Random.nextInt(1, 3)).map { + randomCreditCard().build() + } + name = "Credit Cards" + + overrideBlock?.let { this.it() } + } + + fun randomCreditCard(overrideBlock: (CreditCard.Builder.() -> Unit)? = null) = CreditCard.Builder().apply { + val randomNumber = Random.nextInt(1, 1000) + + id = randomString() + name = "Credit Card $randomNumber" + displayName = "My Credit Card $randomNumber" + bookedBalance = BigDecimal(Random.nextDouble(-10000.0, 0.0)).setScale(2, RoundingMode.HALF_UP).toString() + availableBalance = BigDecimal(Random.nextDouble(1000.0, 15000.0)).setScale(2, RoundingMode.HALF_UP).toString() + creditLimit = BigDecimal(Random.nextDouble(5000.0, 25000.0)).setScale(2, RoundingMode.HALF_UP).toString() + currency = generateRandomCurrency() + number = Random.nextLong(1000000000000000, 9999999999999999).toString() + accountHolderNames = "${listOf("John", "Jane", "Michael", "Sarah").random()} ${listOf("Smith", "Johnson", "Williams", "Brown").random()}" + productTypeName = "Credit Card" + bankAlias = "Credit Card $randomNumber" + validThru = OffsetDateTime.now().plusYears(Random.nextLong(1, 5)) + state = ProductState { + externalStateId = "Active" + state = "Active" + } + userPreferences = UserPreferences { + alias = "My Credit Card $randomNumber" + visible = true + favorite = Random.nextBoolean() + } + + overrideBlock?.let { this.it() } + } + + fun randomLoans(overrideBlock: (Loans.Builder.() -> Unit)? = null) = Loans.Builder().apply { + products = (1..Random.nextInt(1, 2)).map { + randomLoan().build() + } + name = "Loans" + + overrideBlock?.let { this.it() } + } + + fun randomLoan(overrideBlock: (Loan.Builder.() -> Unit)? = null) = Loan.Builder().apply { + val randomNumber = Random.nextInt(1, 1000) + + id = randomString() + name = "Loan $randomNumber" + displayName = "My Loan $randomNumber" + bookedBalance = BigDecimal(Random.nextDouble(-200000.0, -5000.0)).setScale(2, RoundingMode.HALF_UP).toString() + principalAmount = BigDecimal(Random.nextDouble(10000.0, 200000.0)).setScale(2, RoundingMode.HALF_UP) + currency = generateRandomCurrency() + accountHolderNames = "${listOf("John", "Jane", "Michael", "Sarah").random()} ${listOf("Smith", "Johnson", "Williams", "Brown").random()}" + productTypeName = listOf("Personal Loan", "Mortgage", "Car Loan").random() + bankAlias = "Loan $randomNumber" + accountOpeningDate = OffsetDateTime.now().minusDays(Random.nextLong(30, 1000)) + lastUpdateDate = OffsetDateTime.now().minusDays(Random.nextLong(0, 30)) + state = ProductState { + externalStateId = "Active" + state = "Active" + } + userPreferences = UserPreferences { + alias = "My Loan $randomNumber" + visible = true + favorite = false + } + + overrideBlock?.let { this.it() } + } + + fun randomTermDeposits(overrideBlock: (TermDeposits.Builder.() -> Unit)? = null) = TermDeposits.Builder().apply { + products = (1..Random.nextInt(1, 2)).map { + randomTermDeposit().build() + } + name = "Term Deposits" + + overrideBlock?.let { this.it() } + } + + fun randomTermDeposit(overrideBlock: (TermDeposit.Builder.() -> Unit)? = null) = TermDeposit.Builder().apply { + val randomNumber = Random.nextInt(1, 1000) + + id = randomString() + name = "Term Deposit $randomNumber" + displayName = "My Term Deposit $randomNumber" + bookedBalance = BigDecimal(Random.nextDouble(10000.0, 200000.0)).setScale(2, RoundingMode.HALF_UP).toString() + principalAmount = BigDecimal(Random.nextDouble(10000.0, 200000.0)).setScale(2, RoundingMode.HALF_UP) + currency = generateRandomCurrency() + accountInterestRate = BigDecimal(Random.nextDouble(1.0, 6.0)).setScale(3, RoundingMode.HALF_UP) + accountHolderNames = "${listOf("John", "Jane", "Michael", "Sarah").random()} ${listOf("Smith", "Johnson", "Williams", "Brown").random()}" + productTypeName = "Term Deposit" + bankAlias = "Term Deposit $randomNumber" + maturityDate = OffsetDateTime.now().plusYears(Random.nextLong(1, 5)) + accountOpeningDate = OffsetDateTime.now().minusDays(Random.nextLong(30, 1000)) + lastUpdateDate = OffsetDateTime.now().minusDays(Random.nextLong(0, 30)) + state = ProductState { + externalStateId = "Active" + state = "Active" + } + userPreferences = UserPreferences { + alias = "My Term Deposit $randomNumber" + visible = true + favorite = Random.nextBoolean() + } + + overrideBlock?.let { this.it() } + } + + fun randomDebitCards(overrideBlock: (DebitCards.Builder.() -> Unit)? = null) = DebitCards.Builder().apply { + products = (1..Random.nextInt(1, 2)).map { + randomDebitCard().build() + } + name = "Debit Cards" + + overrideBlock?.let { this.it() } + } + + fun randomDebitCard(overrideBlock: (DebitCard.Builder.() -> Unit)? = null) = DebitCard.Builder().apply { + val randomNumber = Random.nextInt(1, 1000) + + id = randomString() + name = "Debit Card $randomNumber" + displayName = "My Debit Card $randomNumber" + number = Random.nextLong(1000000000000000, 9999999999999999).toString() + accountHolderNames = "${listOf("John", "Jane", "Michael", "Sarah").random()} ${listOf("Smith", "Johnson", "Williams", "Brown").random()}" + productTypeName = "Debit Card" + bankAlias = "Debit Card $randomNumber" + validThru = OffsetDateTime.now().plusYears(Random.nextLong(1, 5)) + state = ProductState { + externalStateId = "Active" + state = "Active" + } + userPreferences = UserPreferences { + alias = "My Debit Card $randomNumber" + visible = true + favorite = Random.nextBoolean() + } + + overrideBlock?.let { this.it() } + } + + fun randomInvestmentAccounts(overrideBlock: (InvestmentAccounts.Builder.() -> Unit)? = null) = InvestmentAccounts.Builder().apply { + products = (1..Random.nextInt(1, 2)).map { + randomInvestmentAccount().build() + } + name = "Investment Accounts" + + overrideBlock?.let { this.it() } + } + + fun randomInvestmentAccount(overrideBlock: (InvestmentAccount.Builder.() -> Unit)? = null) = InvestmentAccount.Builder().apply { + val randomNumber = Random.nextInt(1, 1000) + + id = randomString() + name = "Investment Account $randomNumber" + displayName = "My Investment Account $randomNumber" + currentInvestmentValue = BigDecimal(Random.nextDouble(10000.0, 500000.0)).setScale(2, RoundingMode.HALF_UP).toString() + currency = generateRandomCurrency() + accountHolderNames = "${listOf("John", "Jane", "Michael", "Sarah").random()} ${listOf("Smith", "Johnson", "Williams", "Brown").random()}" + productTypeName = "Investment Account" + bankAlias = "Investment Account $randomNumber" + accountOpeningDate = OffsetDateTime.now().minusDays(Random.nextLong(30, 1000)) + lastUpdateDate = OffsetDateTime.now().minusDays(Random.nextLong(0, 30)) + state = ProductState { + externalStateId = "Active" + state = "Active" + } + userPreferences = UserPreferences { + alias = "My Investment Account $randomNumber" + visible = true + favorite = Random.nextBoolean() + } + + overrideBlock?.let { this.it() } + } + + fun randomAdditions(): Map { + return mapOf( + "customField1" to randomString(), + "customField2" to randomString(), + "region" to listOf("US", "EU", "APAC").random(), + "tier" to listOf("Basic", "Premium", "Gold").random() + ) + } +} diff --git a/accounts-test-data/src/main/kotlin/com/backbase/accounts_use_case/StubAccountsUseCases.kt b/accounts-journey-fake/src/main/kotlin/com/backbase/accounts_use_case/FakeAccountsUseCases.kt similarity index 100% rename from accounts-test-data/src/main/kotlin/com/backbase/accounts_use_case/StubAccountsUseCases.kt rename to accounts-journey-fake/src/main/kotlin/com/backbase/accounts_use_case/FakeAccountsUseCases.kt diff --git a/accounts-journey/build.gradle.kts b/accounts-journey/build.gradle.kts index c3bb8672..414c0c11 100644 --- a/accounts-journey/build.gradle.kts +++ b/accounts-journey/build.gradle.kts @@ -33,7 +33,7 @@ android { dependencies { implementation(libs.bundles.navigation) testImplementation(projects.testData) - testImplementation(projects.accountsTestData) + testImplementation(projects.accountsJourneyFake) // Backbase libraries implementation(platform(backbase.bom)) @@ -44,7 +44,7 @@ dependencies { testImplementation(libs.archCore) - androidTestImplementation(projects.accountsTestData) + androidTestImplementation(projects.accountsJourneyFake) androidTestImplementation(projects.testData) androidTestImplementation(libs.bundles.test.instrumented) diff --git a/accounts-journey/src/androidTest/java/app_common/BaseTest.kt b/accounts-journey/src/androidTest/java/app_common/BaseTest.kt index 28505ac7..fa35824a 100644 --- a/accounts-journey/src/androidTest/java/app_common/BaseTest.kt +++ b/accounts-journey/src/androidTest/java/app_common/BaseTest.kt @@ -4,14 +4,12 @@ import android.content.Context import android.content.res.Configuration import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.test.platform.app.InstrumentationRegistry -import kotlinx.coroutines.ExperimentalCoroutinesApi import org.junit.Before import org.junit.Rule import org.koin.core.context.stopKoin import org.koin.test.KoinTest import java.util.Locale -@ExperimentalCoroutinesApi open class BaseTest : KoinTest { @get:Rule @@ -25,8 +23,8 @@ open class BaseTest : KoinTest { } fun setLocale(language: String) { - val context: Context = InstrumentationRegistry.getInstrumentation().getTargetContext() - val config: Configuration = context.getResources().getConfiguration() + val context: Context = InstrumentationRegistry.getInstrumentation().targetContext + val config: Configuration = context.resources.configuration config.setLocale(Locale(language)) context.createConfigurationContext(config) } diff --git a/accounts-journey/src/androidTest/java/screens/AccountListScreen.kt b/accounts-journey/src/androidTest/java/screens/AccountListScreen.kt index 2fb0af49..46f3ad17 100644 --- a/accounts-journey/src/androidTest/java/screens/AccountListScreen.kt +++ b/accounts-journey/src/androidTest/java/screens/AccountListScreen.kt @@ -19,6 +19,7 @@ import com.backbase.android.test_data.shouldBeDisplayed import com.backbase.android.test_data.shouldMatchText import com.backbase.android.test_data.typeTextInInput import screens.components.AccountComponent +import screens.components.AccountHeaderComponent fun accountListScreen(func: AccountListScreen.() -> Unit): AccountListScreen { return AccountListScreen().apply(func) @@ -60,6 +61,10 @@ class AccountListScreen : BaseScreen() { } } + fun accountHeaderWithName(accountHeaderName: String, func: AccountHeaderComponent.() -> Unit): AccountHeaderComponent { + return AccountHeaderComponent(accountHeaderName).apply(func) + } + fun accountWithName(accountName: String, func: AccountComponent.() -> Unit): AccountComponent { return AccountComponent(accountName).apply(func) } diff --git a/accounts-journey/src/androidTest/java/screens/components/AccountHeaderComponent.kt b/accounts-journey/src/androidTest/java/screens/components/AccountHeaderComponent.kt new file mode 100644 index 00000000..ab26c4d0 --- /dev/null +++ b/accounts-journey/src/androidTest/java/screens/components/AccountHeaderComponent.kt @@ -0,0 +1,23 @@ +package screens.components + +import android.view.View +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.ViewInteraction +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import com.backbase.accounts_journey.R +import com.backbase.android.test_data.shouldBeDisplayed +import org.hamcrest.CoreMatchers.allOf +import org.hamcrest.Matcher + +class AccountHeaderComponent(accountHeaderName: String) { + + private val accountHeaderNameMatcher: Matcher = + allOf(withId(R.id.account_header), withText(accountHeaderName)) + + private val accountHeaderText: ViewInteraction = onView(accountHeaderNameMatcher) + + fun accountHeaderIsDisplayed() { + accountHeaderText.shouldBeDisplayed() + } +} diff --git a/accounts-journey/src/androidTest/java/testCases/AccountsListTests.kt b/accounts-journey/src/androidTest/java/testCases/AccountsListTests.kt index 939412d9..966aa50e 100644 --- a/accounts-journey/src/androidTest/java/testCases/AccountsListTests.kt +++ b/accounts-journey/src/androidTest/java/testCases/AccountsListTests.kt @@ -15,12 +15,9 @@ import com.backbase.accounts_journey.generator.AccountSummaryGenerator import com.backbase.accounts_journey.presentation.accountlist.ui.AccountListFragment import com.backbase.accounts_use_case.ErrorAccountsUseCase import com.backbase.accounts_use_case.SuccessAccountsUseCase -import com.backbase.android.test_data.shouldBeDisplayed -import kotlinx.coroutines.ExperimentalCoroutinesApi import org.junit.Test import screens.accountListScreen -@OptIn(ExperimentalCoroutinesApi::class) class AccountsListTests : BaseTest() { @Test @@ -29,7 +26,10 @@ class AccountsListTests : BaseTest() { accountListScreen { headerWithTextIsDisplayed(R.string.accounts_screen_title) - currentAccountsTitle.shouldBeDisplayed() + + accountHeaderWithName(ACCOUNT_HEADER) { + accountHeaderIsDisplayed() + } accountWithName(ACCOUNT_NAME) { accountNameIsDisplayed() @@ -90,7 +90,9 @@ class AccountsListTests : BaseTest() { accountListScreen { pullToRefresh() - currentAccountsTitle.shouldBeDisplayed() + accountHeaderWithName(ACCOUNT_HEADER) { + accountHeaderIsDisplayed() + } } } @@ -100,7 +102,9 @@ class AccountsListTests : BaseTest() { accountListScreen { pullToRefresh() - currentAccountsTitle.shouldBeDisplayed() + accountHeaderWithName(ACCOUNT_HEADER) { + accountHeaderIsDisplayed() + } pullToRefresh() errorViewIsDisplayed(R.string.failed_unknown) } @@ -123,11 +127,20 @@ class AccountsListTests : BaseTest() { } companion object { + const val ACCOUNT_HEADER = "Current Accounts" const val ACCOUNT_NAME = "Alpha" const val ACCOUNT_BALANCE = "45.89" - val TEST_ACCOUNTS = AccountSummaryGenerator.generateAccountSummary( - displayName = ACCOUNT_NAME, - availableBalance = ACCOUNT_BALANCE - ) + + val TEST_ACCOUNTS = AccountSummaryGenerator.randomAccountSummaryBuilder { + currentAccounts = AccountSummaryGenerator.randomCurrentAccounts { + this.name = ACCOUNT_HEADER + this.products = listOf( + AccountSummaryGenerator.randomCurrentAccount { + this.displayName = ACCOUNT_NAME + this.availableBalance = ACCOUNT_BALANCE + }.build() + ) + }.build() + }.build() } } diff --git a/accounts-journey/src/test/java/com/backbase/accounts_journey/presentation/accountdetail/ui/AccountDetailViewModelTest.kt b/accounts-journey/src/test/java/com/backbase/accounts_journey/presentation/accountdetail/ui/AccountDetailViewModelTest.kt index fa454854..5a276ee5 100644 --- a/accounts-journey/src/test/java/com/backbase/accounts_journey/presentation/accountdetail/ui/AccountDetailViewModelTest.kt +++ b/accounts-journey/src/test/java/com/backbase/accounts_journey/presentation/accountdetail/ui/AccountDetailViewModelTest.kt @@ -3,7 +3,7 @@ package com.backbase.accounts_journey.presentation.accountdetail.ui import com.backbase.accounts_journey.common.FailedGetDataException import com.backbase.accounts_journey.data.usecase.AccountDetailUseCase import com.backbase.accounts_journey.data.usecase.Params -import com.backbase.accounts_journey.generator.AccountDetailGenerator.generateAccountDetail +import com.backbase.accounts_journey.generator.AccountDetailGenerator.randomAccountDetailBuilder import com.backbase.accounts_journey.presentation.accountdetail.mapper.AccountDetailUiMapper import com.backbase.android.test_data.CoroutineTest import com.backbase.android.test_data.StringGenerator @@ -38,7 +38,7 @@ class AccountDetailViewModelTest : CoroutineTest { val params = Params({ this.id = id }) coEvery { accountDetailUseCase.getAccountDetail(params) - } returns Result.success(generateAccountDetail(id = id)) + } returns Result.success(randomAccountDetailBuilder {}.apply { this.id = id }.build()) viewModel.onEvent(AccountDetailEvent.OnGetAccountDetail(id)) diff --git a/accounts-journey/src/test/java/com/backbase/accounts_journey/presentation/accountlist/ui/AccountListViewModelTest.kt b/accounts-journey/src/test/java/com/backbase/accounts_journey/presentation/accountlist/ui/AccountListViewModelTest.kt index 66824b92..700c8e1f 100644 --- a/accounts-journey/src/test/java/com/backbase/accounts_journey/presentation/accountlist/ui/AccountListViewModelTest.kt +++ b/accounts-journey/src/test/java/com/backbase/accounts_journey/presentation/accountlist/ui/AccountListViewModelTest.kt @@ -33,7 +33,7 @@ class AccountListViewModelTest : CoroutineTest { @Test fun `should get account summary when success`() = runTest { - val accountSummary = AccountSummaryGenerator.generateAccountSummary() + val accountSummary = AccountSummaryGenerator.randomAccountSummaryBuilder().build() coEvery { accountsUseCase.getAccountSummary(true) } returns Result.success(accountSummary) @@ -58,7 +58,8 @@ class AccountListViewModelTest : CoroutineTest { @Test fun `should get account summary when refresh`() = runTest { - val accountSummary = AccountSummaryGenerator.generateAccountSummary() + val accountSummary = AccountSummaryGenerator.randomAccountSummaryBuilder().build() + coEvery { accountsUseCase.getAccountSummary(false) } returns Result.success(accountSummary) @@ -72,7 +73,13 @@ class AccountListViewModelTest : CoroutineTest { @Test fun `should get account summary when search`() = runTest { val query = randomString() - val accountSummary = AccountSummaryGenerator.generateAccountSummary(displayName = query) + + val accountSummary = AccountSummaryGenerator.randomAccountSummaryBuilder { + currentAccounts = AccountSummaryGenerator.randomCurrentAccounts { + this.products = listOf(AccountSummaryGenerator.randomCurrentAccount { this.displayName = query }.build()) + }.build() + }.build() + coEvery { accountsUseCase.getAccountSummary() } returns Result.success(accountSummary) @@ -87,11 +94,19 @@ class AccountListViewModelTest : CoroutineTest { @Test fun `should get empty account summary when nothing found`() = runTest { val query = randomString() - val accountSummary = AccountSummaryGenerator.generateAccountSummary(displayName = query) + val accountSummary = AccountSummaryGenerator.randomAccountSummaryBuilder { + currentAccounts = AccountSummaryGenerator.randomCurrentAccounts { + this.products = listOf(AccountSummaryGenerator.randomCurrentAccount { this.displayName = query }.build()) + }.build() + }.build() coEvery { accountsUseCase.getAccountSummary() } returns Result.success(accountSummary) + accountSummary.currentAccounts?.products?.forEach { + println(it.displayName) + } + viewModel.onEvent(AccountListEvent.OnSearch(randomString())) val uiState = viewModel.uiState.value diff --git a/accounts-test-data/src/main/kotlin/com/backbase/accounts_journey/generator/AccountDetailGenerator.kt b/accounts-test-data/src/main/kotlin/com/backbase/accounts_journey/generator/AccountDetailGenerator.kt deleted file mode 100644 index c9c4ad1e..00000000 --- a/accounts-test-data/src/main/kotlin/com/backbase/accounts_journey/generator/AccountDetailGenerator.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.backbase.accounts_journey.generator - -import com.backbase.accounts_journey.domain.model.account_detail.AccountDetail -import com.backbase.android.test_data.StringGenerator - -/** - * A random AccountDetail generator. It is not fully implemented, but it gives you an idea how to randomize the data. - */ -object AccountDetailGenerator { - - fun generateAccountDetail( - id: String = StringGenerator.randomString(), - productId: String = StringGenerator.randomString(), - currency: String = StringGenerator.generateRandomCurrency() - ): AccountDetail { - return AccountDetail { - this.id = id - this.productId = productId - this.currency = currency - } - } -} diff --git a/accounts-test-data/src/main/kotlin/com/backbase/accounts_journey/generator/AccountSummaryGenerator.kt b/accounts-test-data/src/main/kotlin/com/backbase/accounts_journey/generator/AccountSummaryGenerator.kt deleted file mode 100644 index b61b2b27..00000000 --- a/accounts-test-data/src/main/kotlin/com/backbase/accounts_journey/generator/AccountSummaryGenerator.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.backbase.accounts_journey.generator - -import com.backbase.accounts_journey.domain.model.account_summary.AccountSummary -import com.backbase.accounts_journey.domain.model.account_summary.MaskableAttribute -import com.backbase.accounts_journey.domain.model.account_summary.UserPreferences -import com.backbase.accounts_journey.domain.model.account_summary.current_accounts.CurrentAccount -import com.backbase.accounts_journey.domain.model.account_summary.current_accounts.CurrentAccounts -import com.backbase.accounts_journey.domain.model.common.ProductState -import com.backbase.android.test_data.NumberGenerator.randomFloat -import com.backbase.android.test_data.StringGenerator.generateRandomBBAN -import com.backbase.android.test_data.StringGenerator.generateRandomBIC -import com.backbase.android.test_data.StringGenerator.generateRandomCurrency -import com.backbase.android.test_data.StringGenerator.randomString -import java.math.BigDecimal -import java.time.OffsetDateTime -import java.time.ZoneOffset -import kotlin.random.Random - -/** - * A random AccountSummary generator. It is not fully implemented, but it gives you an idea how to randomize the data. - */ -object AccountSummaryGenerator { - - fun generateAccountSummary( - id: String = randomString(), - displayName: String = randomString(), - availableBalance: String = randomFloat(1, 100).toString(), - ): AccountSummary { - return AccountSummary { - currentAccounts = CurrentAccounts { - products = listOf( - CurrentAccount { - debitCardItems = emptySet() - bookedBalance = randomFloat().toString() - this.availableBalance = availableBalance - creditLimit = randomFloat().toString() - BBAN = generateRandomBBAN() - BIC = generateRandomBIC() - unMaskableAttributes = setOf(MaskableAttribute.BBAN) - currency = generateRandomCurrency() - bankBranchCode = Random.nextInt(10000, 99999).toString() - bankBranchCode2 = null - accountInterestRate = BigDecimal.ONE - creditLimitUsage = BigDecimal.TEN - creditLimitInterestRate = BigDecimal.ONE - creditLimitExpiryDate = - OffsetDateTime.of(2029, 12, 21, 0, 0, 0, 0, ZoneOffset.UTC) - accruedInterest = BigDecimal.ZERO - accountHolderNames = "Paolo Doe" - startDate = OffsetDateTime.now() - creditAccount = true - debitAccount = true - this.id = id - name = "TESTDATA" - externalTransferAllowed = true - crossCurrencyAllowed = true - productKindName = "Current Account" - productTypeName = "Current Account" - bankAlias = "Paolo's Current Account" - accountOpeningDate = OffsetDateTime.now() - lastUpdateDate = OffsetDateTime.now() - userPreferences = UserPreferences { - alias = "Paolo’s Current Test" - visible = true - favorite = false - } - state = ProductState { - externalStateId = "Active" - state = "Active" - } - this.displayName = displayName - } - ) - name = "Current Accounts" - } - } - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 59b56f58..8f74ea44 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,6 +37,6 @@ include(":app") include(":app-common") include(":accounts-journey") include(":accounts-use-case") -include(":accounts-test-data") +include(":accounts-journey-fake") include(":accounts-demo") include(":test-data")