|
| 1 | +package com.codedifferently.lesson17.bank; |
| 2 | + |
| 3 | +import static org.assertj.core.api.Assertions.assertThat; |
| 4 | + |
| 5 | +import java.util.Set; |
| 6 | +import java.util.UUID; |
| 7 | + |
| 8 | +import org.junit.jupiter.api.BeforeEach; |
| 9 | +import org.junit.jupiter.api.Test; |
| 10 | + |
| 11 | +/** |
| 12 | + * Integration tests for BankAtm to verify support for different account types. |
| 13 | + * These tests focus on validating that SavingsAccount and BusinessCheckingAccount |
| 14 | + * are properly integrated with the BankAtm system. |
| 15 | + */ |
| 16 | +class BankAtmIntegrationTest { |
| 17 | + |
| 18 | + private BankAtm bankAtm; |
| 19 | + |
| 20 | + @BeforeEach |
| 21 | + void setUp() { |
| 22 | + bankAtm = new BankAtm(); |
| 23 | + } |
| 24 | + |
| 25 | + @Test |
| 26 | + void testBankAtmSupportsAllAccountTypes() { |
| 27 | + // Arrange - Create different types of accounts |
| 28 | + Customer regularCustomer = new Customer(UUID.randomUUID(), "John Doe"); |
| 29 | + BusinessCustomer businessCustomer = new BusinessCustomer(UUID.randomUUID(), "ABC Corp"); |
| 30 | + |
| 31 | + CheckingAccount checkingAccount = new CheckingAccount("CHK-001", Set.of(regularCustomer), 1000.0); |
| 32 | + SavingsAccount savingsAccount = new SavingsAccount("SAV-001", Set.of(regularCustomer), 5000.0); |
| 33 | + BusinessCheckingAccount businessAccount = new BusinessCheckingAccount("BIZ-001", "ABC Corp", businessCustomer); |
| 34 | + businessAccount.deposit(10000.0); |
| 35 | + |
| 36 | + // Link accounts to customers |
| 37 | + regularCustomer.addAccount(checkingAccount); |
| 38 | + regularCustomer.addAccount(savingsAccount); |
| 39 | + businessCustomer.addAccount(businessAccount); |
| 40 | + |
| 41 | + // Act - Add all account types to the ATM |
| 42 | + bankAtm.addAccount(checkingAccount); |
| 43 | + bankAtm.addAccount(savingsAccount); |
| 44 | + bankAtm.addAccount(businessAccount); |
| 45 | + |
| 46 | + // Assert - Verify all accounts are accessible |
| 47 | + Set<Account> regularCustomerAccounts = bankAtm.findAccountsByCustomerId(regularCustomer.getId()); |
| 48 | + Set<Account> businessCustomerAccounts = bankAtm.findAccountsByCustomerId(businessCustomer.getId()); |
| 49 | + |
| 50 | + assertThat(regularCustomerAccounts).containsExactlyInAnyOrder(checkingAccount, savingsAccount); |
| 51 | + assertThat(businessCustomerAccounts).containsOnly(businessAccount); |
| 52 | + } |
| 53 | + |
| 54 | + @Test |
| 55 | + void testCashOperationsWorkWithAllAccountTypes() { |
| 56 | + // Arrange |
| 57 | + Customer customer = new Customer(UUID.randomUUID(), "Multi Account Owner"); |
| 58 | + BusinessCustomer businessCustomer = new BusinessCustomer(UUID.randomUUID(), "Business Owner"); |
| 59 | + |
| 60 | + CheckingAccount checkingAccount = new CheckingAccount("CHK-CASH", Set.of(customer), 1000.0); |
| 61 | + SavingsAccount savingsAccount = new SavingsAccount("SAV-CASH", Set.of(customer), 2000.0); |
| 62 | + BusinessCheckingAccount businessAccount = new BusinessCheckingAccount("BIZ-CASH", "Test Business", businessCustomer); |
| 63 | + businessAccount.deposit(5000.0); |
| 64 | + |
| 65 | + customer.addAccount(checkingAccount); |
| 66 | + customer.addAccount(savingsAccount); |
| 67 | + businessCustomer.addAccount(businessAccount); |
| 68 | + |
| 69 | + bankAtm.addAccount(checkingAccount); |
| 70 | + bankAtm.addAccount(savingsAccount); |
| 71 | + bankAtm.addAccount(businessAccount); |
| 72 | + |
| 73 | + // Act & Assert - Test cash deposits |
| 74 | + bankAtm.depositFunds("CHK-CASH", 500.0); |
| 75 | + bankAtm.depositFunds("SAV-CASH", 1000.0); |
| 76 | + bankAtm.depositFunds("BIZ-CASH", 2000.0); |
| 77 | + |
| 78 | + assertThat(checkingAccount.getBalance()).isEqualTo(1500.0); |
| 79 | + assertThat(savingsAccount.getBalance()).isEqualTo(3000.0); |
| 80 | + assertThat(businessAccount.getBalance()).isEqualTo(7000.0); |
| 81 | + |
| 82 | + // Act & Assert - Test cash withdrawals |
| 83 | + bankAtm.withdrawFunds("CHK-CASH", 200.0); |
| 84 | + bankAtm.withdrawFunds("SAV-CASH", 500.0); |
| 85 | + bankAtm.withdrawFunds("BIZ-CASH", 1000.0); |
| 86 | + |
| 87 | + assertThat(checkingAccount.getBalance()).isEqualTo(1300.0); |
| 88 | + assertThat(savingsAccount.getBalance()).isEqualTo(2500.0); |
| 89 | + assertThat(businessAccount.getBalance()).isEqualTo(6000.0); |
| 90 | + } |
| 91 | + |
| 92 | + @Test |
| 93 | + void testCheckOperationsWorkWithAllAccountTypes() { |
| 94 | + // Arrange - Create accounts of different types |
| 95 | + Customer individual = new Customer(UUID.randomUUID(), "Individual Customer"); |
| 96 | + BusinessCustomer business = new BusinessCustomer(UUID.randomUUID(), "Business Customer"); |
| 97 | + |
| 98 | + CheckingAccount sourceChecking = new CheckingAccount("CHK-SOURCE", Set.of(individual), 3000.0); |
| 99 | + SavingsAccount targetSavings = new SavingsAccount("SAV-TARGET", Set.of(individual), 1000.0); |
| 100 | + BusinessCheckingAccount targetBusiness = new BusinessCheckingAccount("BIZ-TARGET", "Target Business", business); |
| 101 | + targetBusiness.deposit(5000.0); |
| 102 | + |
| 103 | + individual.addAccount(sourceChecking); |
| 104 | + individual.addAccount(targetSavings); |
| 105 | + business.addAccount(targetBusiness); |
| 106 | + |
| 107 | + bankAtm.addAccount(sourceChecking); |
| 108 | + bankAtm.addAccount(targetSavings); |
| 109 | + bankAtm.addAccount(targetBusiness); |
| 110 | + |
| 111 | + // Act & Assert - Check from checking to savings |
| 112 | + Check checkToSavings = new Check("SAV-TARGET", 800.0, sourceChecking); |
| 113 | + bankAtm.depositFunds("SAV-TARGET", checkToSavings); |
| 114 | + |
| 115 | + assertThat(sourceChecking.getBalance()).isEqualTo(2200.0); // 3000 - 800 |
| 116 | + assertThat(targetSavings.getBalance()).isEqualTo(1800.0); // 1000 + 800 |
| 117 | + |
| 118 | + // Act & Assert - Check from checking to business account |
| 119 | + Check checkToBusiness = new Check("BIZ-TARGET", 1200.0, sourceChecking); |
| 120 | + bankAtm.depositFunds("BIZ-TARGET", checkToBusiness); |
| 121 | + |
| 122 | + assertThat(sourceChecking.getBalance()).isEqualTo(1000.0); // 2200 - 1200 |
| 123 | + assertThat(targetBusiness.getBalance()).isEqualTo(6200.0); // 5000 + 1200 |
| 124 | + } |
| 125 | + |
| 126 | + @Test |
| 127 | + void testBusinessAccountSpecificFeatures() { |
| 128 | + // Arrange - Business account with business customer |
| 129 | + BusinessCustomer businessOwner = new BusinessCustomer(UUID.randomUUID(), "Tech Startup LLC"); |
| 130 | + BusinessCheckingAccount businessAccount = new BusinessCheckingAccount("BIZ-STARTUP", "Tech Startup LLC", businessOwner); |
| 131 | + businessAccount.deposit(50000.0); |
| 132 | + businessOwner.addAccount(businessAccount); |
| 133 | + |
| 134 | + Customer regularCustomer = new Customer(UUID.randomUUID(), "Regular Customer"); |
| 135 | + CheckingAccount regularAccount = new CheckingAccount("CHK-REGULAR", Set.of(regularCustomer), 2000.0); |
| 136 | + regularCustomer.addAccount(regularAccount); |
| 137 | + |
| 138 | + bankAtm.addAccount(businessAccount); |
| 139 | + bankAtm.addAccount(regularAccount); |
| 140 | + |
| 141 | + // Act & Assert - Business account can perform all standard operations |
| 142 | + bankAtm.depositFunds("BIZ-STARTUP", 10000.0); |
| 143 | + assertThat(businessAccount.getBalance()).isEqualTo(60000.0); |
| 144 | + |
| 145 | + bankAtm.withdrawFunds("BIZ-STARTUP", 5000.0); |
| 146 | + assertThat(businessAccount.getBalance()).isEqualTo(55000.0); |
| 147 | + |
| 148 | + // Business account can write checks |
| 149 | + Check businessCheck = new Check("CHK-REGULAR", 3000.0, businessAccount); |
| 150 | + bankAtm.depositFunds("CHK-REGULAR", businessCheck); |
| 151 | + |
| 152 | + assertThat(businessAccount.getBalance()).isEqualTo(52000.0); // 55000 - 3000 |
| 153 | + assertThat(regularAccount.getBalance()).isEqualTo(5000.0); // 2000 + 3000 |
| 154 | + } |
| 155 | + |
| 156 | + @Test |
| 157 | + void testSavingsAccountSpecificFeatures() { |
| 158 | + // Arrange - Savings account with regular customer |
| 159 | + Customer customer = new Customer(UUID.randomUUID(), "Savings Customer"); |
| 160 | + SavingsAccount savingsAccount = new SavingsAccount("SAV-SPECIAL", Set.of(customer), 10000.0); |
| 161 | + CheckingAccount checkingAccount = new CheckingAccount("CHK-SOURCE", Set.of(customer), 3000.0); |
| 162 | + |
| 163 | + customer.addAccount(savingsAccount); |
| 164 | + customer.addAccount(checkingAccount); |
| 165 | + bankAtm.addAccount(savingsAccount); |
| 166 | + bankAtm.addAccount(checkingAccount); |
| 167 | + |
| 168 | + // Act & Assert - Savings account can receive deposits |
| 169 | + bankAtm.depositFunds("SAV-SPECIAL", 2000.0); |
| 170 | + assertThat(savingsAccount.getBalance()).isEqualTo(12000.0); |
| 171 | + |
| 172 | + // Savings account can have withdrawals |
| 173 | + bankAtm.withdrawFunds("SAV-SPECIAL", 1500.0); |
| 174 | + assertThat(savingsAccount.getBalance()).isEqualTo(10500.0); |
| 175 | + |
| 176 | + // Savings account can receive check deposits |
| 177 | + Check depositCheck = new Check("SAV-SPECIAL", 1000.0, checkingAccount); |
| 178 | + bankAtm.depositFunds("SAV-SPECIAL", depositCheck); |
| 179 | + |
| 180 | + assertThat(savingsAccount.getBalance()).isEqualTo(11500.0); // 10500 + 1000 |
| 181 | + assertThat(checkingAccount.getBalance()).isEqualTo(2000.0); // 3000 - 1000 |
| 182 | + } |
| 183 | + |
| 184 | + @Test |
| 185 | + void testComplexScenarioWithAllAccountTypes() { |
| 186 | + // Arrange - Create a complex scenario with multiple customers and account types |
| 187 | + Customer alice = new Customer(UUID.randomUUID(), "Alice"); |
| 188 | + BusinessCustomer companyXYZ = new BusinessCustomer(UUID.randomUUID(), "Company XYZ"); |
| 189 | + Customer bob = new Customer(UUID.randomUUID(), "Bob"); |
| 190 | + |
| 191 | + // Alice has checking and savings |
| 192 | + CheckingAccount aliceChecking = new CheckingAccount("CHK-ALICE", Set.of(alice), 5000.0); |
| 193 | + SavingsAccount aliceSavings = new SavingsAccount("SAV-ALICE", Set.of(alice), 15000.0); |
| 194 | + |
| 195 | + // Company has business account |
| 196 | + BusinessCheckingAccount companyAccount = new BusinessCheckingAccount("BIZ-XYZ", "Company XYZ", companyXYZ); |
| 197 | + companyAccount.deposit(100000.0); |
| 198 | + |
| 199 | + // Bob has checking |
| 200 | + CheckingAccount bobChecking = new CheckingAccount("CHK-BOB", Set.of(bob), 3000.0); |
| 201 | + |
| 202 | + alice.addAccount(aliceChecking); |
| 203 | + alice.addAccount(aliceSavings); |
| 204 | + companyXYZ.addAccount(companyAccount); |
| 205 | + bob.addAccount(bobChecking); |
| 206 | + |
| 207 | + bankAtm.addAccount(aliceChecking); |
| 208 | + bankAtm.addAccount(aliceSavings); |
| 209 | + bankAtm.addAccount(companyAccount); |
| 210 | + bankAtm.addAccount(bobChecking); |
| 211 | + |
| 212 | + // Act - Simulate a complex transaction scenario |
| 213 | + // 1. Company pays Alice via check |
| 214 | + Check salaryCheck = new Check("CHK-ALICE", 5000.0, companyAccount); |
| 215 | + bankAtm.depositFunds("CHK-ALICE", salaryCheck); |
| 216 | + |
| 217 | + // 2. Alice transfers money to savings |
| 218 | + Check savingsTransfer = new Check("SAV-ALICE", 3000.0, aliceChecking); |
| 219 | + bankAtm.depositFunds("SAV-ALICE", savingsTransfer); |
| 220 | + |
| 221 | + // 3. Alice pays Bob |
| 222 | + Check paymentToBob = new Check("CHK-BOB", 1500.0, aliceChecking); |
| 223 | + bankAtm.depositFunds("CHK-BOB", paymentToBob); |
| 224 | + |
| 225 | + // 4. Bob deposits cash |
| 226 | + bankAtm.depositFunds("CHK-BOB", 500.0); |
| 227 | + |
| 228 | + // Assert - Verify all balances |
| 229 | + assertThat(companyAccount.getBalance()).isEqualTo(95000.0); // 100000 - 5000 |
| 230 | + assertThat(aliceChecking.getBalance()).isEqualTo(5500.0); // 5000 + 5000 - 3000 - 1500 |
| 231 | + assertThat(aliceSavings.getBalance()).isEqualTo(18000.0); // 15000 + 3000 |
| 232 | + assertThat(bobChecking.getBalance()).isEqualTo(5000.0); // 3000 + 1500 + 500 |
| 233 | + } |
| 234 | +} |
0 commit comments