Skip to content

Commit 5be8fe8

Browse files
committed
Implement funds withdrawals in the domain
Make sure only the domain functional test is run using junit5 tags for conditional execution.
1 parent c149302 commit 5be8fe8

10 files changed

Lines changed: 57 additions & 0 deletions

File tree

domain/src/main/kotlin/lmirabal/bank/Bank.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ interface Bank {
88
fun createAccount(): BankAccount
99
fun listAccounts(): List<BankAccount>
1010
fun deposit(id: BankAccountId, amount: Amount): BankAccount
11+
fun withdraw(id: BankAccountId, amount: Amount): BankAccount
1112
}

domain/src/main/kotlin/lmirabal/bank/BankService.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,10 @@ class BankService(
2121
return account.deposit(amount)
2222
.also { updatedAccount -> accountRepository.update(updatedAccount) }
2323
}
24+
25+
override fun withdraw(id: BankAccountId, amount: Amount): BankAccount {
26+
val account = accountRepository.list().first { it.id == id }
27+
return account.withdraw(amount)
28+
.also { updatedAccount -> accountRepository.update(updatedAccount) }
29+
}
2430
}

domain/src/main/kotlin/lmirabal/bank/model/Amount.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ data class Amount(val minorUnits: Long) {
99
return Amount(minorUnits + other.minorUnits)
1010
}
1111

12+
operator fun minus(other: Amount): Amount {
13+
return Amount(minorUnits - other.minorUnits)
14+
}
15+
1216
companion object {
1317
val ZERO = Amount(0)
1418
}

domain/src/main/kotlin/lmirabal/bank/model/BankAccount.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ data class BankAccount(val id: BankAccountId, val balance: Amount) {
66
fun deposit(amount: Amount): BankAccount {
77
return copy(balance = balance + amount)
88
}
9+
10+
fun withdraw(amount: Amount): BankAccount {
11+
return copy(balance = balance - amount)
12+
}
913
}
1014

1115
data class BankAccountId(val value: UUID) {

domain/src/test/kotlin/lmirabal/bank/BankServiceTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import lmirabal.bank.data.InMemoryBankAccountRepository
66
import lmirabal.bank.model.Amount
77
import lmirabal.bank.model.BankAccount
88
import lmirabal.bank.model.BankAccountId
9+
import org.junit.jupiter.api.Tag
910
import org.junit.jupiter.api.Test
1011

12+
@Tag("ImplementationReady")
1113
class BankServiceTest : BankTest() {
1214
private val idFactory = RecordingIdFactory()
1315
override val bank = BankService(InMemoryBankAccountRepository(), idFactory)

domain/src/test/kotlin/lmirabal/bank/model/AmountTest.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,11 @@ class AmountTest {
1717

1818
assertThat(result, equalTo(Amount(40)))
1919
}
20+
21+
@Test
22+
fun subtracts() {
23+
val result = Amount(30) - Amount(10)
24+
25+
assertThat(result, equalTo(Amount(20)))
26+
}
2027
}

domain/src/test/kotlin/lmirabal/bank/model/BankAccountTest.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,14 @@ class BankAccountTest {
1414

1515
assertThat(updatedAccount, equalTo(BankAccount(id, Amount(300))))
1616
}
17+
18+
@Test
19+
fun `decreases balance on withdrawal`() {
20+
val id = BankAccountId.random()
21+
val account = BankAccount(id, Amount(300))
22+
23+
val updatedAccount = account.withdraw(Amount(200))
24+
25+
assertThat(updatedAccount, equalTo(BankAccount(id, Amount(100))))
26+
}
1727
}

domain/src/testFixtures/kotlin/lmirabal/bank/BankTest.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import com.natpryce.hamkrest.assertion.assertThat
44
import com.natpryce.hamkrest.equalTo
55
import lmirabal.bank.model.Amount
66
import org.junit.jupiter.api.Test
7+
import org.junit.jupiter.api.condition.EnabledIf
8+
import org.junit.jupiter.api.extension.ExtensionContext
79

810
abstract class BankTest {
911
abstract val bank: Bank
@@ -27,4 +29,17 @@ abstract class BankTest {
2729

2830
assertThat(updatedAccount.balance, equalTo(Amount(300)))
2931
}
32+
33+
@EnabledIf("implementationReady")
34+
@Test
35+
fun `withdraws from account`() {
36+
val bankAccount = bank.createAccount()
37+
38+
bank.deposit(bankAccount.id, Amount(300))
39+
val updatedAccount = bank.withdraw(bankAccount.id, Amount(200))
40+
41+
assertThat(updatedAccount.balance, equalTo(Amount(100)))
42+
}
43+
44+
fun implementationReady(context: ExtensionContext) = "ImplementationReady" in context.tags
3045
}

http/src/main/kotlin/lmirabal/bank/http/BankHttpClient.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@ class BankHttpClient(val http: HttpHandler) : Bank {
2828
)
2929
return bankAccountLens(response)
3030
}
31+
32+
override fun withdraw(id: BankAccountId, amount: Amount): BankAccount {
33+
TODO("Not yet implemented")
34+
}
3135
}

web/src/test/kotlin/lmirabal/bank/web/BankWebTest.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class BankWebDriver(web: HttpHandler) : Bank {
6161
return driver.getBankAccounts().first { account -> account.id == id }
6262
}
6363

64+
override fun withdraw(id: BankAccountId, amount: Amount): BankAccount {
65+
TODO("Not yet implemented")
66+
}
67+
6468
private fun WebElement.getBankAccountId(): BankAccountId {
6569
val idText = getTableColumn(ID_INDEX)
6670
return BankAccountId(UUID.fromString(idText))

0 commit comments

Comments
 (0)