Skip to content

Commit 097000c

Browse files
committed
✨ Add new bank
1 parent 6e63300 commit 097000c

File tree

5 files changed

+66
-10
lines changed

5 files changed

+66
-10
lines changed

src/main/kotlin/com/rsginer/hackathoon/banks/controller/BankController.kt

+7
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,17 @@ class BankController(
1616
fun handleNotFound(e: NoSuchElementException): ResponseEntity<String> =
1717
ResponseEntity(e.message, HttpStatus.NOT_FOUND)
1818

19+
@ExceptionHandler(IllegalArgumentException::class)
20+
fun handleBadRequest(e: IllegalArgumentException): ResponseEntity<String> =
21+
ResponseEntity(e.message, HttpStatus.BAD_REQUEST)
22+
1923
@GetMapping
2024
fun getBanks(): Collection<Bank> = this.bankService.getBanks()
2125

2226
@GetMapping("/{accountNumber}")
2327
fun getBankByAccountNumber(@PathVariable accountNumber: String): Bank = this.bankService.getBank(accountNumber)
2428

29+
@PostMapping
30+
@ResponseStatus(HttpStatus.CREATED)
31+
fun addBank(@RequestBody bank: Bank): Bank = bankService.addBank(bank)
2532
}

src/main/kotlin/com/rsginer/hackathoon/banks/datasource/BankDataSource.kt

+1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ import com.rsginer.hackathoon.banks.model.Bank
55
interface BankDataSource {
66
fun retrieveBanks(): Collection<Bank>
77
fun retrieveBank(accountNumber: String): Bank
8+
fun createBank(bank: Bank): Bank
89
}

src/main/kotlin/com/rsginer/hackathoon/banks/datasource/mock/MockBankDataSource.kt

+13-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ package com.rsginer.hackathoon.banks.datasource.mock
33
import com.rsginer.hackathoon.banks.datasource.BankDataSource
44
import com.rsginer.hackathoon.banks.model.Bank
55
import org.springframework.stereotype.Repository
6+
import java.lang.IllegalArgumentException
67

78
@Repository
89
class MockBankDataSource : BankDataSource {
910

10-
private val banks = listOf(
11+
private val banks = mutableListOf<Bank>(
1112
Bank("12345", 0.1, 1),
1213
Bank("10101", 0.1, 2),
1314
Bank("50505", 1.0, 100)
@@ -16,4 +17,15 @@ class MockBankDataSource : BankDataSource {
1617
override fun retrieveBanks(): Collection<Bank> = banks
1718
override fun retrieveBank(accountNumber: String): Bank = banks.firstOrNull() { it.accountNumber == accountNumber }
1819
?: throw NoSuchElementException("Could not find a bank with accountNumber $accountNumber")
20+
21+
override fun createBank(bank: Bank): Bank {
22+
23+
if (banks.any { it.accountNumber == bank.accountNumber }) {
24+
throw IllegalArgumentException("Bank with accountNumber ${bank.accountNumber} already exist")
25+
}
26+
27+
banks.add(bank)
28+
29+
return bank
30+
}
1931
}

src/main/kotlin/com/rsginer/hackathoon/banks/service/BankService.kt

+2
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ class BankService(
1212

1313
fun getBank(accountNumber: String) = dataSource.retrieveBank(accountNumber)
1414

15+
fun addBank(bank: Bank) = dataSource.createBank(bank)
16+
1517
}

src/test/kotlin/com/rsginer/hackathoon/banks/controller/BankControllerTest.kt

+43-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.rsginer.hackathoon.banks.controller
22

3+
import com.fasterxml.jackson.databind.ObjectMapper
4+
import com.rsginer.hackathoon.banks.model.Bank
35
import org.junit.jupiter.api.Assertions.*
46
import org.junit.jupiter.api.DisplayName
57
import org.junit.jupiter.api.Nested
@@ -11,16 +13,17 @@ import org.springframework.boot.test.context.SpringBootTest
1113
import org.springframework.http.MediaType
1214
import org.springframework.test.web.servlet.MockMvc
1315
import org.springframework.test.web.servlet.get
16+
import org.springframework.test.web.servlet.post
1417

1518
@SpringBootTest
1619
@AutoConfigureMockMvc
17-
internal class BankControllerTest {
18-
19-
@Autowired
20-
lateinit var mockMvc: MockMvc
20+
internal class BankControllerTest @Autowired constructor(
21+
val mockMvc: MockMvc,
22+
val objectMapper: ObjectMapper
23+
) {
2124

2225
@Nested
23-
@DisplayName("getBanks()")
26+
@DisplayName("GET /api/banks")
2427
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
2528
inner class GetBanks {
2629
@Test
@@ -41,12 +44,10 @@ internal class BankControllerTest {
4144
}
4245
}
4346
}
44-
45-
4647
}
4748

4849
@Nested
49-
@DisplayName("getBank()")
50+
@DisplayName("GET /api/banks/{accountNumber}")
5051
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
5152
inner class GetBank {
5253
@Test
@@ -74,6 +75,39 @@ internal class BankControllerTest {
7475
}
7576
}
7677
}
77-
78+
79+
@Nested
80+
@DisplayName("POST /api/banks")
81+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
82+
inner class PostNewBank {
83+
84+
@Test
85+
fun `should add new bank`() {
86+
val newBank = Bank("54321", 34.0, 2)
87+
88+
mockMvc.post("/api/banks") {
89+
contentType = MediaType.APPLICATION_JSON
90+
content = objectMapper.writeValueAsString(newBank)
91+
}
92+
.andDo { print() }
93+
.andExpect {
94+
status { isCreated() }
95+
jsonPath("$.accountNumber") { value("54321") }
96+
jsonPath("$.trust") { value("34.0") }
97+
}
98+
}
99+
100+
@Test
101+
fun `should return BAD REQUEST if accountNumber already exist`() {
102+
val invalidBank = Bank("12345", 20.0, 2)
103+
104+
mockMvc.post("/api/banks") {
105+
contentType = MediaType.APPLICATION_JSON
106+
content = objectMapper.writeValueAsString(invalidBank)
107+
}
108+
.andDo { print() }
109+
.andExpect { status { isBadRequest() } }
110+
}
111+
}
78112

79113
}

0 commit comments

Comments
 (0)