Add ktlint config
This commit is contained in:
parent
fb471f8100
commit
9212d23933
17
api/.editorconfig
Normal file
17
api/.editorconfig
Normal file
@ -0,0 +1,17 @@
|
||||
# editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{kt, kts}]
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
disabled_rules = no-wildcard-imports
|
||||
kotlin_imports_layout = idea
|
||||
@ -44,7 +44,6 @@ val mainModule = DI.Module("main") {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
bind<SimpleJWT>(tag = "auth") with singleton { simpleJwtFactory(instance<Config>().jwt.auth) }
|
||||
bind<SimpleJWT>(tag = "refresh") with singleton { simpleJwtFactory(instance<Config>().jwt.refresh) }
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@ import org.kodein.di.instance
|
||||
import org.slf4j.Logger
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
fun main() {
|
||||
val di = DI { import(mainModule) }
|
||||
val config by di.instance<Config>()
|
||||
@ -41,7 +40,6 @@ fun serve(di: DI) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun Application.module(di: DI) {
|
||||
val builders: Set<ApplicationBuilder> by di.instance()
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ import io.ktor.response.*
|
||||
import io.ktor.utils.io.errors.*
|
||||
import java.sql.SQLTransientConnectionException
|
||||
|
||||
|
||||
class ErrorHandler : ApplicationBuilder({
|
||||
install(StatusPages) {
|
||||
|
||||
|
||||
@ -40,7 +40,6 @@ fun StatusPages.Configuration.jacksonErrors() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class InvalidFormatError(val value: Any?, targetType: Class<*>) {
|
||||
val msg = "Wrong type"
|
||||
val required = targetType.simpleName
|
||||
|
||||
@ -8,7 +8,6 @@ import kotlinx.coroutines.launch
|
||||
import org.flywaydb.core.Flyway
|
||||
import javax.sql.DataSource
|
||||
|
||||
|
||||
class MigrationHook(migration: Migration) : ApplicationBuilder({
|
||||
environment.monitor.subscribe(ApplicationStarted) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
|
||||
@ -29,7 +29,6 @@ class NoteRoutes(noteService: NoteService) : RoutingBuilder({
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
private fun Route.createNote(noteService: NoteService) {
|
||||
post {
|
||||
val userId = call.authenticatedUserId()
|
||||
@ -42,7 +41,7 @@ private fun Route.createNote(noteService: NoteService) {
|
||||
private fun Route.getAllNotes(noteService: NoteService) {
|
||||
get {
|
||||
val userId = call.authenticatedUserId()
|
||||
val limit = call.parameters["limit"]?.toInt() ?: 20// FIXME validate
|
||||
val limit = call.parameters["limit"]?.toInt() ?: 20 // FIXME validate
|
||||
val after = call.parameters["after"]?.let { UUID.fromString(it) } // FIXME validate
|
||||
val notes = noteService.findAll(userId, limit, after)
|
||||
call.respond(notes)
|
||||
|
||||
@ -59,7 +59,6 @@ private fun Route.deleteUser(userService: UserService) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun Route.createUser(userService: UserService) {
|
||||
post {
|
||||
val user = call.receiveValidated(registerValidator)
|
||||
@ -74,7 +73,6 @@ private fun Route.createUser(userService: UserService) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun Route.login(
|
||||
userService: UserService,
|
||||
passwordHash: PasswordHash,
|
||||
@ -99,7 +97,6 @@ private fun Route.login(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun Route.refreshToken(userService: UserService, authJWT: SimpleJWT, refreshJWT: SimpleJWT) {
|
||||
post {
|
||||
val token = call.receive<RefreshToken>().refreshToken
|
||||
|
||||
@ -61,7 +61,6 @@ class NoteService(private val db: Database) {
|
||||
db.sequenceOf(Notes, withReferences = false).any { it.userId eq userId and (it.uuid eq uuid) }
|
||||
}
|
||||
|
||||
|
||||
suspend fun create(userId: Int, note: Note): Note = launchIo {
|
||||
val uuid = UUID.randomUUID()
|
||||
val newNote = note.copy().apply {
|
||||
@ -79,7 +78,6 @@ class NoteService(private val db: Database) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
newNote
|
||||
}
|
||||
@ -126,7 +124,6 @@ class NoteService(private val db: Database) {
|
||||
it.noteUuid to note.uuid
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
@ -27,7 +27,6 @@ class UserService(private val db: Database, private val passwordHash: PasswordHa
|
||||
.find { it.id eq id }
|
||||
}
|
||||
|
||||
|
||||
suspend fun exists(username: String) = launchIo {
|
||||
db.sequenceOf(Users, withReferences = false)
|
||||
.any { it.username eq username }
|
||||
@ -65,6 +64,4 @@ class UserService(private val db: Database, private val passwordHash: PasswordHa
|
||||
else -> error("??")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,6 @@ class AuthControllerKtTest {
|
||||
|
||||
private val passwordHash by kodein.instance<PasswordHash>()
|
||||
|
||||
|
||||
init {
|
||||
|
||||
val user = User {
|
||||
@ -63,7 +62,6 @@ class AuthControllerKtTest {
|
||||
coEvery { userService.find(3) } returns null
|
||||
}
|
||||
|
||||
|
||||
private val testEngine = TestApplicationEngine().apply {
|
||||
start()
|
||||
application.module(kodein)
|
||||
@ -136,7 +134,6 @@ class AuthControllerKtTest {
|
||||
}
|
||||
res.status() `should be equal to` HttpStatusCode.BadRequest
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@ -195,7 +192,6 @@ class AuthControllerKtTest {
|
||||
res.status() `should be equal to` HttpStatusCode.Unauthorized
|
||||
res.content `should strictly be equal to json` """{msg: "Unauthorized"}"""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@ -224,6 +220,4 @@ class AuthControllerKtTest {
|
||||
jsonObject.keyList() `should be equal to` listOf("msg")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -38,10 +38,8 @@ class UserControllerKtTest {
|
||||
coEvery { userService.exists(and(not("modified"), not("existing"))) } returns false
|
||||
coEvery { userService.exists(1) } returns true
|
||||
coEvery { userService.create("modified", any()) } returns null
|
||||
|
||||
}
|
||||
|
||||
|
||||
private val kodein = DI {
|
||||
import(mainModule, allowOverride = true)
|
||||
bind<UserService>(overrides = true) with instance(userService)
|
||||
@ -79,7 +77,6 @@ class UserControllerKtTest {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
inner class DeleteUser {
|
||||
|
||||
@ -102,5 +99,4 @@ class UserControllerKtTest {
|
||||
res2.content `should be equal to json` """{msg:"Not Found"}"""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -47,15 +47,20 @@ class NoteServiceTest {
|
||||
val user = runBlocking { userService.create("test", "test")!! }
|
||||
val noteService by kodein.instance<NoteService>()
|
||||
val note = runBlocking {
|
||||
noteService.create(user.id, Note {
|
||||
this.title = "a note"
|
||||
this.content = """# Title
|
||||
|
|
||||
|😝😝😝😝
|
||||
|another line
|
||||
""".trimMargin()
|
||||
this.tags = listOf("a", "tag")
|
||||
})
|
||||
noteService.create(
|
||||
user.id,
|
||||
Note {
|
||||
this.title = "a note"
|
||||
this.content =
|
||||
"""
|
||||
|# Title
|
||||
|
|
||||
|😝😝😝😝
|
||||
|another line
|
||||
""".trimMargin()
|
||||
this.tags = listOf("a", "tag")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
println(note)
|
||||
@ -78,26 +83,38 @@ class NoteServiceTest {
|
||||
|
||||
val noteService by kodein.instance<NoteService>()
|
||||
runBlocking {
|
||||
noteService.create(user.id, Note {
|
||||
title = "test"
|
||||
content = ""
|
||||
tags = listOf("same")
|
||||
})
|
||||
noteService.create(user.id, Note {
|
||||
title = "test2"
|
||||
content = ""
|
||||
tags = listOf("same")
|
||||
})
|
||||
noteService.create(user.id, Note {
|
||||
title = "test3"
|
||||
content = ""
|
||||
tags = listOf("another")
|
||||
})
|
||||
noteService.create(user2.id, Note {
|
||||
title = "test"
|
||||
content = ""
|
||||
tags = listOf("user2")
|
||||
})
|
||||
noteService.create(
|
||||
user.id,
|
||||
Note {
|
||||
title = "test"
|
||||
content = ""
|
||||
tags = listOf("same")
|
||||
}
|
||||
)
|
||||
noteService.create(
|
||||
user.id,
|
||||
Note {
|
||||
title = "test2"
|
||||
content = ""
|
||||
tags = listOf("same")
|
||||
}
|
||||
)
|
||||
noteService.create(
|
||||
user.id,
|
||||
Note {
|
||||
title = "test3"
|
||||
content = ""
|
||||
tags = listOf("another")
|
||||
}
|
||||
)
|
||||
noteService.create(
|
||||
user2.id,
|
||||
Note {
|
||||
title = "test"
|
||||
content = ""
|
||||
tags = listOf("user2")
|
||||
}
|
||||
)
|
||||
}
|
||||
val user1Tags = runBlocking { noteService.getTags(user.id) }
|
||||
user1Tags `should be equal to` listOf("same", "another")
|
||||
@ -111,27 +128,30 @@ class NoteServiceTest {
|
||||
val userService by kodein.instance<UserService>()
|
||||
val user = runBlocking { userService.create(Faker().name().username(), "test") }!!
|
||||
val note = runBlocking {
|
||||
noteService.create(user.id, Note {
|
||||
this.title = "title"
|
||||
this.content = "old content"
|
||||
this.tags = emptyList()
|
||||
})
|
||||
noteService.create(
|
||||
user.id,
|
||||
Note {
|
||||
this.title = "title"
|
||||
this.content = "old content"
|
||||
this.tags = emptyList()
|
||||
}
|
||||
)
|
||||
}
|
||||
val get = runBlocking { noteService.find(user.id, note.uuid) }
|
||||
|
||||
runBlocking {
|
||||
noteService.updateNote(user.id, Note {
|
||||
uuid = note.uuid
|
||||
title = "new title"
|
||||
})
|
||||
noteService.updateNote(
|
||||
user.id,
|
||||
Note {
|
||||
uuid = note.uuid
|
||||
title = "new title"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val updated = runBlocking { noteService.find(user.id, note.uuid) }
|
||||
println("updated: $updated")
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@ -150,58 +170,70 @@ class NoteServiceTest {
|
||||
val hasTags = note["tags"] != null && note.tags.isNotEmpty()
|
||||
return hasTitle || hasContent || hasTags
|
||||
}
|
||||
|
||||
}
|
||||
val userValidator: Validator<Note> = ValidatorBuilder<Note>()
|
||||
.constraintOnTarget(fieldPresentConstraint, "present")
|
||||
.build()
|
||||
|
||||
userValidator.validate(Note {
|
||||
title = "this is a title"
|
||||
}).isValid `should be equal to` true
|
||||
userValidator.validate(
|
||||
Note {
|
||||
title = "this is a title"
|
||||
}
|
||||
).isValid `should be equal to` true
|
||||
|
||||
userValidator.validate(Note {
|
||||
content = "this is a title"
|
||||
}).isValid `should be equal to` true
|
||||
userValidator.validate(
|
||||
Note {
|
||||
content = "this is a title"
|
||||
}
|
||||
).isValid `should be equal to` true
|
||||
|
||||
userValidator.validate(Note {
|
||||
tags = emptyList()
|
||||
}).isValid `should be equal to` false
|
||||
userValidator.validate(
|
||||
Note {
|
||||
tags = emptyList()
|
||||
}
|
||||
).isValid `should be equal to` false
|
||||
|
||||
userValidator.validate(Note {
|
||||
tags = listOf("tags")
|
||||
}).isValid `should be equal to` true
|
||||
userValidator.validate(
|
||||
Note {
|
||||
tags = listOf("tags")
|
||||
}
|
||||
).isValid `should be equal to` true
|
||||
|
||||
userValidator.validate(Note {
|
||||
tags = listOf("tags")
|
||||
title = "This is a title"
|
||||
}).isValid `should be equal to` true
|
||||
userValidator.validate(
|
||||
Note {
|
||||
tags = listOf("tags")
|
||||
title = "This is a title"
|
||||
}
|
||||
).isValid `should be equal to` true
|
||||
|
||||
userValidator.validate(Note {
|
||||
tags = listOf("tags")
|
||||
title = "This is a title"
|
||||
content = """
|
||||
# This is
|
||||
userValidator.validate(
|
||||
Note {
|
||||
tags = listOf("tags")
|
||||
title = "This is a title"
|
||||
content =
|
||||
"""
|
||||
|# This is
|
||||
|
|
||||
|some markdown content
|
||||
""".trimMargin()
|
||||
}
|
||||
).isValid `should be equal to` true
|
||||
|
||||
some markdown content
|
||||
""".trimIndent()
|
||||
}).isValid `should be equal to` true
|
||||
|
||||
userValidator.validate(Note {
|
||||
tags = listOf("tags")
|
||||
title = "This is a title"
|
||||
content = """
|
||||
# This is
|
||||
|
||||
some markdown content
|
||||
""".trimIndent()
|
||||
}).isValid `should be equal to` true
|
||||
userValidator.validate(
|
||||
Note {
|
||||
tags = listOf("tags")
|
||||
title = "This is a title"
|
||||
content =
|
||||
"""
|
||||
|# This is
|
||||
|
|
||||
|some markdown content
|
||||
""".trimMargin()
|
||||
}
|
||||
).isValid `should be equal to` true
|
||||
|
||||
userValidator.validate(Note()).isValid `should be equal to` false
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@ -222,6 +254,4 @@ class NoteServiceTest {
|
||||
println(note.uuid.mostSignificantBits)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -12,7 +12,6 @@ import org.kodein.di.instance
|
||||
import org.kodein.di.singleton
|
||||
import utils.KMariadbContainer
|
||||
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
|
||||
class UserServiceTest {
|
||||
@ -21,7 +20,7 @@ class UserServiceTest {
|
||||
|
||||
private val kodein = DI {
|
||||
import(mainModule, allowOverride = true)
|
||||
bind( overrides = true) from singleton { mariadb.datasource() }
|
||||
bind(overrides = true) from singleton { mariadb.datasource() }
|
||||
}
|
||||
|
||||
private val userService by kodein.instance<UserService>()
|
||||
@ -64,5 +63,4 @@ class UserServiceTest {
|
||||
userService.find(id) `should be` null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,21 +11,24 @@ class RegisterValidationTest {
|
||||
|
||||
@Test
|
||||
fun `valid register test`() {
|
||||
val violations = registerValidator.validate(User {
|
||||
username = "hubert"
|
||||
password = "definitelyNotMyPassword"
|
||||
})
|
||||
val violations = registerValidator.validate(
|
||||
User {
|
||||
username = "hubert"
|
||||
password = "definitelyNotMyPassword"
|
||||
}
|
||||
)
|
||||
|
||||
violations.isValid `should be equal to` true
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `username too long test`() {
|
||||
val violations = registerValidator.validate(User {
|
||||
username = "6X9iboWmEOWjVjkO328ReTJ1gGPTTmB/ZGgBLhB6EzAJoWkJht8"
|
||||
password = "definitelyNotMyPassword"
|
||||
})
|
||||
val violations = registerValidator.validate(
|
||||
User {
|
||||
username = "6X9iboWmEOWjVjkO328ReTJ1gGPTTmB/ZGgBLhB6EzAJoWkJht8"
|
||||
password = "definitelyNotMyPassword"
|
||||
}
|
||||
)
|
||||
|
||||
violations.isValid `should be equal to` false
|
||||
violations.firstInvalid `should be equal to` "username"
|
||||
|
||||
@ -3,10 +3,9 @@ package utils
|
||||
import com.zaxxer.hikari.HikariConfig
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import org.testcontainers.containers.MariaDBContainer
|
||||
import javax.sql.DataSource
|
||||
|
||||
class KMariadbContainer : MariaDBContainer<KMariadbContainer>() {
|
||||
fun datasource() : HikariDataSource {
|
||||
fun datasource(): HikariDataSource {
|
||||
val hikariConfig = HikariConfig().apply {
|
||||
jdbcUrl = this@KMariadbContainer.jdbcUrl
|
||||
username = this@KMariadbContainer.username
|
||||
@ -5,7 +5,6 @@ import io.ktor.http.HttpMethod
|
||||
import io.ktor.server.testing.*
|
||||
import org.json.JSONObject
|
||||
|
||||
|
||||
fun TestApplicationRequest.json(block: (JSONObject) -> Unit) {
|
||||
addHeader(HttpHeaders.ContentType, "application/json")
|
||||
setBody(JSONObject().apply(block).toString())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user