-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
578 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ | |
# Ignore Gradle build output directory | ||
build | ||
.idea | ||
**/videos |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
services: | ||
postgres: | ||
container_name: postgres | ||
image: postgres | ||
ports: | ||
- 5432:5432 | ||
environment: | ||
- POSTGRES_PASSWORD=password | ||
- POSTGRES_DB=fsabank | ||
fsabank: | ||
container_name: fsabank | ||
build: | ||
dockerfile: web/Dockerfile | ||
context: .. | ||
depends_on: | ||
- postgres | ||
environment: | ||
- DB_HOST=postgres | ||
- DB_NAME=fsabank | ||
- DB_PASSWORD=password | ||
- DB_USERNAME=postgres | ||
ports: | ||
- 5000:8080 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 32 additions & 4 deletions
36
core/src/test/kotlin/fr/arsenelapostolet/fsa_banking_system/bank/BankApplicationTests.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,50 @@ | ||
package fr.arsenelapostolet.fsa_banking_system.bank | ||
|
||
import fr.arsenelapostolet.fsa_banking_system.bank.entities.Account | ||
import kotlinx.coroutines.runBlocking | ||
import org.junit.jupiter.api.Assertions.assertEquals | ||
import org.junit.jupiter.api.Assertions.assertTrue | ||
import org.junit.jupiter.api.Test | ||
|
||
class BankApplicationTests { | ||
|
||
val target: BankApplication = BankApplication(FakeAccountRepository()) | ||
private val repository = FakeAccountRepository() | ||
private val target: BankApplication = BankApplication(repository) | ||
|
||
@Test | ||
fun createAccount_insertsRecord(){ | ||
fun createAccount_insertsRecord() = runBlocking { | ||
// Given | ||
val accountName = "test account"; | ||
|
||
// When | ||
target.createAccount(accountName) | ||
val result = target.createAccount(accountName) | ||
|
||
// Then | ||
|
||
assertEquals(accountName, result.name) | ||
assertEquals(accountName, repository.data[accountName]!!.name) | ||
} | ||
|
||
@Test | ||
fun listAccounts_returnsAccountsInDb() = runBlocking { | ||
// Given | ||
val accounts = listOf( | ||
Account("Test account 1"), | ||
Account("Test account 2"), | ||
Account("Test account 3") | ||
) | ||
for(account in accounts){ | ||
repository.data[account.name] = account | ||
} | ||
|
||
// When | ||
val result = target.listAccounts() | ||
|
||
// Then | ||
assertEquals(3, result.size) | ||
for(account in accounts){ | ||
assertTrue(result.contains(account)) | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
FROM gradle:8.2.0-jdk17 AS build | ||
WORKDIR /app | ||
COPY . . | ||
RUN gradle buildFatJar --no-daemon | ||
|
||
FROM openjdk:17 AS run | ||
EXPOSE 8080 | ||
RUN mkdir /app | ||
COPY --from=build /app/web/build/libs/web-all.jar /app/web-all.jar | ||
ENTRYPOINT ["java","-jar","/app/web-all.jar"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 47 additions & 8 deletions
55
web/src/main/kotlin/fr/arsenelapostolet/fsa_banking_system/app/App.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,53 @@ | ||
package fr.arsenelapostolet.fsa_banking_system.app | ||
|
||
import io.ktor.server.application.* | ||
import fr.arsenelapostolet.fsa_banking_system.app.database.DatabaseAccounts | ||
import fr.arsenelapostolet.fsa_banking_system.app.database.PostgresAccountRepository | ||
import fr.arsenelapostolet.fsa_banking_system.bank.BankApplication | ||
import fr.arsenelapostolet.fsa_banking_system.bank.persistance.AccountRepository | ||
import io.ktor.server.engine.* | ||
import io.ktor.server.netty.* | ||
import io.r2dbc.spi.ConnectionFactories | ||
import io.r2dbc.spi.ConnectionFactoryOptions | ||
import kotlinx.coroutines.runBlocking | ||
import org.kodein.di.* | ||
import org.kodein.di.ktor.* | ||
import org.ufoss.kotysa.PostgresqlR2dbcSqlClient | ||
import org.ufoss.kotysa.PostgresqlTables | ||
import org.ufoss.kotysa.R2dbcSqlClient | ||
import org.ufoss.kotysa.r2dbc.coSqlClient | ||
import org.ufoss.kotysa.tables | ||
|
||
fun main() { | ||
embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module) | ||
.start(wait = true) | ||
} | ||
|
||
fun Application.module() { | ||
configureRouting() | ||
} | ||
embeddedServer(Netty, port = 8080, host = "0.0.0.0") { | ||
di { | ||
bind<PostgresqlR2dbcSqlClient>() with singleton { | ||
ConnectionFactories | ||
.get( | ||
ConnectionFactoryOptions.builder() | ||
.option(ConnectionFactoryOptions.DRIVER, "postgresql") | ||
.option(ConnectionFactoryOptions.HOST, System.getenv("DB_HOST")) | ||
.option(ConnectionFactoryOptions.USER, System.getenv("DB_USERNAME")) | ||
.option(ConnectionFactoryOptions.PASSWORD, System.getenv("DB_PASSWORD")) | ||
.option(ConnectionFactoryOptions.DATABASE, System.getenv("DB_NAME")) | ||
.build() | ||
) | ||
.coSqlClient(tables().postgresql(DatabaseAccounts)) | ||
} | ||
bind<AccountRepository> { | ||
singleton { | ||
PostgresAccountRepository(instance()) | ||
} | ||
} | ||
bind<BankApplication> { | ||
singleton { | ||
BankApplication(instance()) | ||
} | ||
} | ||
} | ||
runBlocking { | ||
val client by closestDI().instance<R2dbcSqlClient>() | ||
client createTable DatabaseAccounts | ||
} | ||
configureRouting() | ||
}.start(wait = true) | ||
} |
106 changes: 104 additions & 2 deletions
106
web/src/main/kotlin/fr/arsenelapostolet/fsa_banking_system/app/Routing.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,115 @@ | ||
package fr.arsenelapostolet.fsa_banking_system.app | ||
|
||
import fr.arsenelapostolet.fsa_banking_system.app.templates.PageTemplate | ||
import fr.arsenelapostolet.fsa_banking_system.bank.BankApplication | ||
import io.ktor.http.* | ||
import io.ktor.server.routing.* | ||
import io.ktor.server.response.* | ||
import io.ktor.server.application.* | ||
import io.ktor.server.html.* | ||
import io.ktor.server.http.content.* | ||
import io.ktor.server.request.* | ||
import kotlinx.html.* | ||
import org.kodein.di.instance | ||
import org.kodein.di.ktor.closestDI | ||
|
||
fun Application.configureRouting() { | ||
routing { | ||
get("/") { | ||
call.respondText("Hello World!") | ||
staticResources("/static", ".") | ||
get("/accounts") { | ||
val bankingApp by closestDI().instance<BankApplication>() | ||
val accounts = bankingApp.listAccounts() | ||
|
||
call.respondHtmlTemplate(PageTemplate(), HttpStatusCode.OK) { | ||
content { | ||
div(classes = "center") { | ||
div(classes = "box") { | ||
h1(classes = "title") { | ||
+"Accounts" | ||
} | ||
table(classes = "table is-striped") { | ||
thead { | ||
tr { | ||
th { | ||
+"Account Name" | ||
} | ||
th { | ||
+"Actions" | ||
} | ||
} | ||
} | ||
tbody { | ||
accounts.map { | ||
tr { | ||
td { +it.name } | ||
td("is-flex") { | ||
button(classes = "button") { | ||
+"View" | ||
} | ||
button(classes = "button is-danger") { | ||
+"Delete" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
button (classes = "button"){ | ||
+ "Pay salaries" | ||
} | ||
a(href = "/accounts/create") { | ||
button(classes = "button is-primary") { | ||
+"Create new account" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
get("/accounts/create") { | ||
call.respondHtmlTemplate(PageTemplate(), HttpStatusCode.OK) { | ||
content { | ||
div(classes = "center") { | ||
|
||
form(action = "/accounts/create", method = FormMethod.post, classes = "box") { | ||
h1(classes = "title") { | ||
+"Create new Account" | ||
} | ||
div(classes = "field") { | ||
label(classes = "label") { | ||
+"Holder Account Name :" | ||
} | ||
div(classes = "control") { | ||
textInput(name = "holderName", classes = "input") | ||
} | ||
|
||
} | ||
div(classes = "control") { | ||
submitInput(classes = "button is-primary") { value = "Create Account" } | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
post("/accounts/create") { | ||
val formParameters = call.receiveParameters() | ||
val bankingApp by closestDI().instance<BankApplication>() | ||
|
||
val holderName = formParameters["holderName"] | ||
if (holderName == null) { | ||
call.respondHtml(HttpStatusCode.BadRequest) { | ||
body { | ||
p { | ||
"holderName is required" | ||
} | ||
} | ||
} | ||
} | ||
|
||
bankingApp.createAccount(holderName!!) | ||
call.respondRedirect("/accounts", permanent = true) | ||
} | ||
} | ||
} |
Oops, something went wrong.