[no_ci] Add friend routes
continuous-integration/drone/push Build is passing Details

pull/12/head
luevard 11 months ago
parent 7c49c34167
commit d4da0fd3f6

@ -38,7 +38,7 @@ val Application.dataSource: AllInDataSource
get() = allInDataSource get() = allInDataSource
fun main() { fun main() {
embeddedServer(Netty, port = 8080, host = "0.0.0.0") { embeddedServer(Netty, port = 10001, host = "0.0.0.0") {
extracted() extracted()
}.start(wait = true) }.start(wait = true)
} }
@ -85,6 +85,7 @@ private fun Application.extracted() {
betRouter() betRouter()
participationRouter() participationRouter()
betDetailRouter() betDetailRouter()
friendRouter()
kronJob(BET_VERIFY_DELAY) { kronJob(BET_VERIFY_DELAY) {
dataSource.betDataSource.updateBetStatuses(ZonedDateTime.now()) dataSource.betDataSource.updateBetStatuses(ZonedDateTime.now())

@ -1,11 +1,8 @@
package allin.data package allin.data
import allin.model.User
interface FriendDataSource { interface FriendDataSource {
fun addFriend(sender: String, receiver: String) fun addFriend(sender: String, receiver: String)
fun getFriendFromUserId(id: String): List<User> fun getFriendFromUserId(id: String): List<String>
fun getFriendFromUsername(username: String) fun deleteFriend(senderId: String, receiverId: String): Boolean
fun deleteFriend(senderId: String, receiverId: String) fun isFriend(firstUser: String, secondUser: String): Boolean
fun isFriend(firstUser: String, secondUser: String)
} }

@ -1,26 +1,22 @@
package allin.data.mock package allin.data.mock
import allin.data.FriendDataSource import allin.data.FriendDataSource
import allin.model.User
class MockFriendDataSource(mockData: MockDataSource.MockData) : FriendDataSource { class MockFriendDataSource(mockData: MockDataSource.MockData) : FriendDataSource {
override fun addFriend(sender: String, receiver: String) { override fun addFriend(sender: String, receiver: String) {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override fun getFriendFromUserId(id: String): List<User> { override fun getFriendFromUserId(id: String): List<String> {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override fun getFriendFromUsername(username: String) { override fun deleteFriend(senderId: String, receiverId: String): Boolean {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override fun deleteFriend(senderId: String, receiverId: String) { override fun isFriend(firstUser: String, secondUser: String): Boolean {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override fun isFriend(firstUser: String, secondUser: String) {
TODO("Not yet implemented")
}
} }

@ -1,33 +1,42 @@
package allin.data.postgres package allin.data.postgres
import allin.data.FriendDataSource import allin.data.FriendDataSource
import allin.data.postgres.entities.FriendsEntity import allin.data.postgres.entities.FriendEntity
import allin.model.User import allin.data.postgres.entities.friends
import org.ktorm.database.Database import org.ktorm.database.Database
import org.ktorm.dsl.insert import org.ktorm.dsl.and
import org.ktorm.dsl.eq
import org.ktorm.entity.add
import org.ktorm.entity.filter
import org.ktorm.entity.map
import org.ktorm.entity.removeIf
class PostgresFriendDataSource(private val database: Database) : FriendDataSource { class PostgresFriendDataSource(private val database: Database) : FriendDataSource {
override fun addFriend(sender: String, receiver: String) { override fun addFriend(sender: String, receiver: String) {
database.insert(FriendsEntity) { database.friends.add(
set(it.sender, sender) FriendEntity {
set(it.receiver, receiver) this.sender = sender
} this.receiver = receiver
}
)
} }
override fun getFriendFromUserId(id: String): List<User> { override fun getFriendFromUserId(id: String): List<String> {
TODO() val friendList = database.friends.map { it.toFriend() }
val friendPairs = friendList.map { it.sender to it.receiver }.toSet()
return friendList
.filter { it.sender == id }
.map { it.receiver }
} }
override fun getFriendFromUsername(username: String) { override fun deleteFriend(senderId: String, receiverId: String): Boolean {
TODO("Not yet implemented") database.friends.removeIf { it.sender eq senderId }
} return database.friends.removeIf { it.sender eq senderId } > 0
override fun deleteFriend(senderId: String, receiverId: String) {
TODO("Not yet implemented")
}
override fun isFriend(firstUser: String, secondUser: String) {
TODO("Not yet implemented")
} }
override fun isFriend(firstUser: String, secondUser: String) =
database.friends
.filter { (it.sender eq firstUser) and (it.receiver eq secondUser) }
.map { it.toFriend() }
.isNotEmpty()
} }

@ -1,15 +1,29 @@
package allin.data.postgres.entities package allin.data.postgres.entities
import allin.model.Friend
import org.ktorm.database.Database
import org.ktorm.entity.Entity import org.ktorm.entity.Entity
import org.ktorm.entity.sequenceOf
import org.ktorm.schema.Table import org.ktorm.schema.Table
import org.ktorm.schema.varchar import org.ktorm.schema.varchar
interface FriendEntity : Entity<FriendEntity> { interface FriendEntity : Entity<FriendEntity> {
val sender: String companion object : Entity.Factory<FriendEntity>()
val receiver: String
var sender: String
var receiver: String
fun toFriend() =
Friend(
sender = sender,
receiver = receiver,
)
} }
object FriendsEntity : Table<FriendEntity>("friend") { object FriendsEntity : Table<FriendEntity>("friend") {
val sender = varchar("id").primaryKey().bindTo { it.sender } val sender = varchar("sender").primaryKey().bindTo { it.sender }
val receiver = varchar("bet").primaryKey().bindTo { it.receiver } val receiver = varchar("receiver").primaryKey().bindTo { it.receiver }
} }
val Database.friends get() = this.sequenceOf(FriendsEntity)

@ -13,4 +13,7 @@ object ApiMessage {
const val NOT_ENOUGH_COINS = "Not enough coins." const val NOT_ENOUGH_COINS = "Not enough coins."
const val NO_GIFT = "Can't get daily gift." const val NO_GIFT = "Can't get daily gift."
const val USER_CANT_BE_DELETE = "This user can't be delete now !" const val USER_CANT_BE_DELETE = "This user can't be delete now !"
const val FRIENDS_ALREADY_EXISTS = "User already exists in your Friends List."
const val FRIENDS_DOESNT_EXISTS = "User already exists in your Friends List."
} }

@ -0,0 +1,7 @@
package allin.model
data class Friend(
val sender: String,
val receiver: String
)

@ -0,0 +1,114 @@
package allin.routing
import allin.dataSource
import allin.ext.hasToken
import allin.model.ApiMessage
import io.github.smiley4.ktorswaggerui.dsl.post
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Application.friendRouter() {
val userDataSource = this.dataSource.userDataSource
val friendDataSource = this.dataSource.friendDataSource
routing {
authenticate {
post("/friend/add", {
description = "Allows a user to add a friend"
request {
headerParameter<JWTPrincipal>("JWT token of the logged user")
body<String> {
description = "User to add in the friends list"
}
}
response {
HttpStatusCode.Created to {
description = "the friend has been added"
body<String>() {
description = "Friend with assigned id"
}
}
HttpStatusCode.Conflict to {
description = "Friend already exist in the friends list"
body(ApiMessage.FRIENDS_ALREADY_EXISTS)
}
}
}) {
hasToken { principal ->
val requestMap = call.receive<Map<String, String>>()
val usernameFriend = requestMap["username"] ?: return@hasToken call.respond(HttpStatusCode.BadRequest, "Username is missing")
val username = tokenManagerBet.getUsernameFromToken(principal)
val user = userDataSource.getUserByUsername(username).first
val userFriend = userDataSource.getUserByUsername(usernameFriend).first
if (user == null || userFriend == null) {
call.respond(HttpStatusCode.Conflict, ApiMessage.USER_NOT_FOUND)
} else {
val friendlist = friendDataSource.getFriendFromUserId(user.id)
if (friendlist.contains(userFriend.id)) {
call.respond(HttpStatusCode.Conflict,ApiMessage.FRIENDS_ALREADY_EXISTS)
} else {
friendDataSource.addFriend(user.id, userFriend.id)
call.respond(HttpStatusCode.Created, usernameFriend)
}
}
}
}
post("/friend/delete", {
description = "Allows a user to delete a friend"
request {
headerParameter<JWTPrincipal>("JWT token of the logged user")
body<String> {
description = "User to delete in the friends list"
}
}
response {
HttpStatusCode.Created to {
description = "the friend has been delete"
body<String>() {
description = "Friend with assigned id"
}
}
HttpStatusCode.Conflict to {
description = "Friend doesn't exist in the friends list"
body(ApiMessage.FRIENDS_DOESNT_EXISTS)
}
}
}) {
hasToken { principal ->
val requestMap = call.receive<Map<String, String>>()
val usernameFriend = requestMap["username"] ?: return@hasToken call.respond(HttpStatusCode.BadRequest, "Username is missing")
val username = tokenManagerBet.getUsernameFromToken(principal)
val user = userDataSource.getUserByUsername(username).first
val userFriend = userDataSource.getUserByUsername(usernameFriend).first
if (user == null || userFriend == null) {
call.respond(HttpStatusCode.Conflict, ApiMessage.USER_NOT_FOUND)
} else {
val friendlist = friendDataSource.getFriendFromUserId(user.id)
if (!friendlist.contains(userFriend.id)) {
call.respond(HttpStatusCode.Conflict,ApiMessage.FRIENDS_DOESNT_EXISTS)
} else {
friendDataSource.deleteFriend(user.id, userFriend.id)
call.respond(HttpStatusCode.Created, usernameFriend)
}
}
}
}
}
}
}
Loading…
Cancel
Save