mirror of
https://github.com/arcan1s/ffxivbis.git
synced 2025-04-24 17:27:17 +00:00
add support of party alias
This commit is contained in:
parent
1e6064e081
commit
16ce0bf61c
@ -0,0 +1,5 @@
|
||||
create table parties (
|
||||
player_id bigserial unique,
|
||||
party_name text not null,
|
||||
party_alias text);
|
||||
create unique index parties_party_name_idx on parties(party_name);
|
@ -0,0 +1,5 @@
|
||||
create table parties (
|
||||
player_id integer primary key autoincrement,
|
||||
party_name text not null,
|
||||
party_alias text);
|
||||
create unique index parties_party_name_idx on parties(party_name);
|
@ -16,7 +16,9 @@ import me.arcanis.ffxivbis.service.Ariyala
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
class AriyalaHelper(ariyala: ActorRef) {
|
||||
trait AriyalaHelper {
|
||||
|
||||
def ariyala: ActorRef
|
||||
|
||||
def downloadBiS(link: String, job: Job.Job)
|
||||
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[BiS] =
|
||||
|
@ -17,7 +17,9 @@ import me.arcanis.ffxivbis.service.impl.DatabaseBiSHandler
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
class BiSHelper(storage: ActorRef, ariyala: ActorRef) extends AriyalaHelper(ariyala) {
|
||||
trait BiSHelper extends AriyalaHelper {
|
||||
|
||||
def storage: ActorRef
|
||||
|
||||
def addPieceBiS(playerId: PlayerId, piece: Piece)
|
||||
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] =
|
||||
|
@ -18,7 +18,9 @@ import me.arcanis.ffxivbis.service.impl.DatabaseLootHandler
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
class LootHelper(storage: ActorRef) {
|
||||
trait LootHelper {
|
||||
|
||||
def storage: ActorRef
|
||||
|
||||
def addPieceLoot(playerId: PlayerId, piece: Piece)
|
||||
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] =
|
||||
|
@ -12,12 +12,14 @@ import akka.actor.ActorRef
|
||||
import akka.pattern.ask
|
||||
import akka.util.Timeout
|
||||
import me.arcanis.ffxivbis.http.api.v1.json.ApiAction
|
||||
import me.arcanis.ffxivbis.models.{Party, Player, PlayerId}
|
||||
import me.arcanis.ffxivbis.models.{Party, PartyDescription, Player, PlayerId}
|
||||
import me.arcanis.ffxivbis.service.impl.{DatabaseBiSHandler, DatabasePartyHandler}
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
class PlayerHelper(storage: ActorRef, ariyala: ActorRef) extends AriyalaHelper(ariyala) {
|
||||
trait PlayerHelper extends AriyalaHelper {
|
||||
|
||||
def storage: ActorRef
|
||||
|
||||
def addPlayer(player: Player)
|
||||
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] =
|
||||
@ -38,6 +40,10 @@ class PlayerHelper(storage: ActorRef, ariyala: ActorRef) extends AriyalaHelper(a
|
||||
case ApiAction.remove => removePlayer(player.playerId)
|
||||
}
|
||||
|
||||
def getPartyDescription(partyId: String)
|
||||
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[PartyDescription] =
|
||||
(storage ? DatabasePartyHandler.GetPartyDescription(partyId)).mapTo[PartyDescription]
|
||||
|
||||
def getPlayers(partyId: String, maybePlayerId: Option[PlayerId])
|
||||
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Seq[Player]] =
|
||||
maybePlayerId match {
|
||||
@ -50,4 +56,8 @@ class PlayerHelper(storage: ActorRef, ariyala: ActorRef) extends AriyalaHelper(a
|
||||
def removePlayer(playerId: PlayerId)
|
||||
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] =
|
||||
(storage ? DatabasePartyHandler.RemovePlayer(playerId)).mapTo[Int]
|
||||
|
||||
def updateDescription(partyDescription: PartyDescription)
|
||||
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] =
|
||||
(storage ? DatabasePartyHandler.UpdateParty(partyDescription)).mapTo[Int]
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ import scala.io.Source
|
||||
class Swagger(config: Config) extends SwaggerHttpService {
|
||||
override val apiClasses: Set[Class[_]] = Set(
|
||||
classOf[api.v1.BiSEndpoint], classOf[api.v1.LootEndpoint],
|
||||
classOf[api.v1.PlayerEndpoint], classOf[api.v1.TypesEndpoint],
|
||||
classOf[api.v1.UserEndpoint]
|
||||
classOf[api.v1.PartyEndpoint], classOf[api.v1.PlayerEndpoint],
|
||||
classOf[api.v1.TypesEndpoint], classOf[api.v1.UserEndpoint]
|
||||
)
|
||||
|
||||
override val info: Info = Info(
|
||||
|
@ -17,7 +17,9 @@ import me.arcanis.ffxivbis.service.impl.DatabaseUserHandler
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
class UserHelper(storage: ActorRef) {
|
||||
trait UserHelper {
|
||||
|
||||
def storage: ActorRef
|
||||
|
||||
def addUser(user: User, isHashedPassword: Boolean)
|
||||
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] =
|
||||
|
@ -27,8 +27,8 @@ import me.arcanis.ffxivbis.models.PlayerId
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
@Path("api/v1")
|
||||
class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends BiSHelper(storage, ariyala) with Authorization with JsonSupport {
|
||||
class BiSEndpoint(override val storage: ActorRef, override val ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends BiSHelper with Authorization with JsonSupport {
|
||||
|
||||
def route: Route = createBiS ~ getBiS ~ modifyBiS
|
||||
|
||||
|
@ -28,7 +28,7 @@ import scala.util.{Failure, Success}
|
||||
|
||||
@Path("api/v1")
|
||||
class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
|
||||
extends LootHelper(storage) with Authorization with JsonSupport with HttpHandler {
|
||||
extends LootHelper with Authorization with JsonSupport with HttpHandler {
|
||||
|
||||
def route: Route = getLoot ~ modifyLoot
|
||||
|
||||
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Evgeniy Alekseev.
|
||||
*
|
||||
* This file is part of ffxivbis
|
||||
* (see https://github.com/arcan1s/ffxivbis).
|
||||
*
|
||||
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package me.arcanis.ffxivbis.http.api.v1
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import akka.http.scaladsl.model.{HttpEntity, StatusCodes}
|
||||
import akka.http.scaladsl.server.Directives._
|
||||
import akka.http.scaladsl.server._
|
||||
import akka.util.Timeout
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn
|
||||
import io.swagger.v3.oas.annotations.media.{Content, Schema}
|
||||
import io.swagger.v3.oas.annotations.parameters.RequestBody
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement
|
||||
import io.swagger.v3.oas.annotations.{Operation, Parameter}
|
||||
import javax.ws.rs._
|
||||
import me.arcanis.ffxivbis.http.api.v1.json._
|
||||
import me.arcanis.ffxivbis.http.{Authorization, PlayerHelper}
|
||||
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
@Path("api/v1")
|
||||
class PartyEndpoint(override val storage: ActorRef, override val ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends PlayerHelper with Authorization with JsonSupport with HttpHandler {
|
||||
|
||||
def route: Route = getPartyDescription ~ modifyPartyDescription
|
||||
|
||||
@GET
|
||||
@Path("party/{partyId}/description")
|
||||
@Produces(value = Array("application/json"))
|
||||
@Operation(summary = "get party description", description = "Return the party description",
|
||||
parameters = Array(
|
||||
new Parameter(name = "partyId", in = ParameterIn.PATH, description = "unique party ID", example = "abcdefgh"),
|
||||
),
|
||||
responses = Array(
|
||||
new ApiResponse(responseCode = "200", description = "Party description",
|
||||
content = Array(new Content(schema = new Schema(implementation = classOf[PartyDescriptionResponse])))),
|
||||
new ApiResponse(responseCode = "401", description = "Supplied authorization is invalid",
|
||||
content = Array(new Content(schema = new Schema(implementation = classOf[ErrorResponse])))),
|
||||
new ApiResponse(responseCode = "403", description = "Access is forbidden",
|
||||
content = Array(new Content(schema = new Schema(implementation = classOf[ErrorResponse])))),
|
||||
new ApiResponse(responseCode = "500", description = "Internal server error",
|
||||
content = Array(new Content(schema = new Schema(implementation = classOf[ErrorResponse])))),
|
||||
),
|
||||
security = Array(new SecurityRequirement(name = "basic auth", scopes = Array("get"))),
|
||||
tags = Array("party"),
|
||||
)
|
||||
def getPartyDescription: Route =
|
||||
path("party" / Segment / "description") { partyId =>
|
||||
extractExecutionContext { implicit executionContext =>
|
||||
authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
|
||||
get {
|
||||
onComplete(getPartyDescription(partyId)) {
|
||||
case Success(response) => complete(PartyDescriptionResponse.fromDescription(response))
|
||||
case Failure(exception) => throw exception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes(value = Array("application/json"))
|
||||
@Path("party/{partyId}/description")
|
||||
@Operation(summary = "modify party description", description = "Edit party description",
|
||||
parameters = Array(
|
||||
new Parameter(name = "partyId", in = ParameterIn.PATH, description = "unique party ID", example = "abcdefgh"),
|
||||
),
|
||||
requestBody = new RequestBody(description = "new party description", required = true,
|
||||
content = Array(new Content(schema = new Schema(implementation = classOf[PartyDescriptionResponse])))),
|
||||
responses = Array(
|
||||
new ApiResponse(responseCode = "202", description = "Party description has been modified"),
|
||||
new ApiResponse(responseCode = "400", description = "Invalid parameters were supplied",
|
||||
content = Array(new Content(schema = new Schema(implementation = classOf[ErrorResponse])))),
|
||||
new ApiResponse(responseCode = "401", description = "Supplied authorization is invalid",
|
||||
content = Array(new Content(schema = new Schema(implementation = classOf[ErrorResponse])))),
|
||||
new ApiResponse(responseCode = "403", description = "Access is forbidden",
|
||||
content = Array(new Content(schema = new Schema(implementation = classOf[ErrorResponse])))),
|
||||
new ApiResponse(responseCode = "500", description = "Internal server error",
|
||||
content = Array(new Content(schema = new Schema(implementation = classOf[ErrorResponse])))),
|
||||
),
|
||||
security = Array(new SecurityRequirement(name = "basic auth", scopes = Array("post"))),
|
||||
tags = Array("party"),
|
||||
)
|
||||
def modifyPartyDescription: Route =
|
||||
path("party" / Segment / "description") { partyId =>
|
||||
extractExecutionContext { implicit executionContext =>
|
||||
authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ =>
|
||||
post {
|
||||
entity(as[PartyDescriptionResponse]) { partyDescription =>
|
||||
val description = partyDescription.copy(partyId = partyId)
|
||||
onComplete(updateDescription(description.toDescription)) {
|
||||
case Success(_) => complete(StatusCodes.Accepted, HttpEntity.Empty)
|
||||
case Failure(exception) => throw exception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -27,8 +27,8 @@ import me.arcanis.ffxivbis.models.PlayerId
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
@Path("api/v1")
|
||||
class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends PlayerHelper(storage, ariyala) with Authorization with JsonSupport with HttpHandler {
|
||||
class PlayerEndpoint(override val storage: ActorRef, override val ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends PlayerHelper with Authorization with JsonSupport with HttpHandler {
|
||||
|
||||
def route: Route = getParty ~ modifyParty
|
||||
|
||||
|
@ -21,6 +21,7 @@ class RootApiV1Endpoint(storage: ActorRef, ariyala: ActorRef, config: Config)
|
||||
|
||||
private val biSEndpoint = new BiSEndpoint(storage, ariyala)
|
||||
private val lootEndpoint = new LootEndpoint(storage)
|
||||
private val partyEndpoint = new PartyEndpoint(storage, ariyala)
|
||||
private val playerEndpoint = new PlayerEndpoint(storage, ariyala)
|
||||
private val typesEndpoint = new TypesEndpoint(config)
|
||||
private val userEndpoint = new UserEndpoint(storage)
|
||||
@ -28,8 +29,8 @@ class RootApiV1Endpoint(storage: ActorRef, ariyala: ActorRef, config: Config)
|
||||
def route: Route =
|
||||
handleExceptions(exceptionHandler) {
|
||||
handleRejections(rejectionHandler) {
|
||||
biSEndpoint.route ~ lootEndpoint.route ~ playerEndpoint.route ~
|
||||
typesEndpoint.route ~ userEndpoint.route
|
||||
biSEndpoint.route ~ lootEndpoint.route ~ partyEndpoint.route ~
|
||||
playerEndpoint.route ~ typesEndpoint.route ~ userEndpoint.route
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import scala.util.{Failure, Success}
|
||||
|
||||
@Path("api/v1")
|
||||
class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
|
||||
extends UserHelper(storage) with Authorization with JsonSupport {
|
||||
extends UserHelper with Authorization with JsonSupport {
|
||||
|
||||
def route: Route = createParty ~ createUser ~ deleteUser ~ getUsers
|
||||
|
||||
|
@ -42,6 +42,7 @@ trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
|
||||
implicit val partyIdFormat: RootJsonFormat[PartyIdResponse] = jsonFormat1(PartyIdResponse.apply)
|
||||
implicit val pieceFormat: RootJsonFormat[PieceResponse] = jsonFormat3(PieceResponse.apply)
|
||||
implicit val lootFormat: RootJsonFormat[LootResponse] = jsonFormat2(LootResponse.apply)
|
||||
implicit val partyDescriptionFormat: RootJsonFormat[PartyDescriptionResponse] = jsonFormat2(PartyDescriptionResponse.apply)
|
||||
implicit val playerFormat: RootJsonFormat[PlayerResponse] = jsonFormat7(PlayerResponse.apply)
|
||||
implicit val playerActionFormat: RootJsonFormat[PlayerActionResponse] = jsonFormat2(PlayerActionResponse.apply)
|
||||
implicit val playerIdFormat: RootJsonFormat[PlayerIdResponse] = jsonFormat3(PlayerIdResponse.apply)
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Evgeniy Alekseev.
|
||||
*
|
||||
* This file is part of ffxivbis
|
||||
* (see https://github.com/arcan1s/ffxivbis).
|
||||
*
|
||||
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package me.arcanis.ffxivbis.http.api.v1.json
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import me.arcanis.ffxivbis.models.PartyDescription
|
||||
|
||||
case class PartyDescriptionResponse(
|
||||
@Schema(description = "party id", required = true) partyId: String,
|
||||
@Schema(description = "party name") partyAlias: Option[String]) {
|
||||
def toDescription: PartyDescription = PartyDescription(partyId, partyAlias)
|
||||
}
|
||||
|
||||
object PartyDescriptionResponse {
|
||||
def fromDescription(description: PartyDescription): PartyDescriptionResponse =
|
||||
PartyDescriptionResponse(description.partyId, description.partyAlias)
|
||||
}
|
@ -13,10 +13,12 @@ import akka.http.scaladsl.model.StatusCodes
|
||||
import akka.http.scaladsl.server.Directives._
|
||||
import akka.http.scaladsl.server._
|
||||
import akka.util.Timeout
|
||||
import me.arcanis.ffxivbis.http.Authorization
|
||||
import me.arcanis.ffxivbis.http.{Authorization, PlayerHelper}
|
||||
|
||||
class BasePartyView(override val storage: ActorRef)(implicit timeout: Timeout)
|
||||
extends Authorization {
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
class BasePartyView(override val storage: ActorRef, override val ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends PlayerHelper with Authorization {
|
||||
|
||||
def route: Route = getIndex
|
||||
|
||||
@ -25,8 +27,10 @@ class BasePartyView(override val storage: ActorRef)(implicit timeout: Timeout)
|
||||
extractExecutionContext { implicit executionContext =>
|
||||
authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
|
||||
get {
|
||||
complete {
|
||||
(StatusCodes.OK, RootView.toHtml(BasePartyView.template(partyId)))
|
||||
onComplete(getPartyDescription(partyId)) {
|
||||
case Success(description) =>
|
||||
complete(StatusCodes.OK, RootView.toHtml(BasePartyView.template(partyId, description.alias)))
|
||||
case Failure(exception) => throw exception
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,16 +46,16 @@ object BasePartyView {
|
||||
def root(partyId: String): Text.TypedTag[String] =
|
||||
a(href:=s"/party/$partyId", title:="root")("root")
|
||||
|
||||
def template(partyId: String): String =
|
||||
def template(partyId: String, alias: String): String =
|
||||
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
|
||||
html(lang:="en",
|
||||
head(
|
||||
titleTag(s"Party $partyId"),
|
||||
titleTag(s"Party $alias"),
|
||||
link(rel:="stylesheet", `type`:="text/css", href:="/static/styles.css")
|
||||
),
|
||||
|
||||
body(
|
||||
h2(s"Party $partyId"),
|
||||
h2(s"Party $alias"),
|
||||
br,
|
||||
h2(a(href:=s"/party/$partyId/players", title:="party")("party")),
|
||||
h2(a(href:=s"/party/$partyId/bis", title:="bis management")("best in slot")),
|
||||
|
@ -19,8 +19,8 @@ import me.arcanis.ffxivbis.models.{Piece, Player, PlayerId}
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.Try
|
||||
|
||||
class BiSView(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends BiSHelper(storage, ariyala) with Authorization {
|
||||
class BiSView(override val storage: ActorRef, override val ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends BiSHelper with Authorization {
|
||||
|
||||
def route: Route = getBiS ~ modifyBiS
|
||||
|
||||
|
@ -13,13 +13,14 @@ import akka.http.scaladsl.model.StatusCodes
|
||||
import akka.http.scaladsl.server.Directives._
|
||||
import akka.http.scaladsl.server._
|
||||
import akka.util.Timeout
|
||||
import me.arcanis.ffxivbis.http.UserHelper
|
||||
import me.arcanis.ffxivbis.models.{Permission, User}
|
||||
import me.arcanis.ffxivbis.http.{PlayerHelper, UserHelper}
|
||||
import me.arcanis.ffxivbis.models.{PartyDescription, Permission, User}
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
class IndexView(storage: ActorRef)(implicit timeout: Timeout)
|
||||
extends UserHelper(storage) {
|
||||
class IndexView(override val storage: ActorRef, override val ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends PlayerHelper with UserHelper {
|
||||
|
||||
def route: Route = createParty ~ getIndex
|
||||
|
||||
@ -27,13 +28,17 @@ class IndexView(storage: ActorRef)(implicit timeout: Timeout)
|
||||
path("party") {
|
||||
extractExecutionContext { implicit executionContext =>
|
||||
post {
|
||||
formFields("username".as[String], "password".as[String]) { (username, password) =>
|
||||
onComplete(newPartyId) {
|
||||
case Success(partyId) =>
|
||||
formFields("username".as[String], "password".as[String], "alias".as[String].?) { (username, password, maybeAlias) =>
|
||||
onComplete {
|
||||
newPartyId.flatMap { partyId =>
|
||||
val user = User(partyId, username, password, Permission.admin)
|
||||
onComplete(addUser(user, isHashedPassword = false)) {
|
||||
case _ => redirect(s"/party/$partyId", StatusCodes.Found)
|
||||
addUser(user, isHashedPassword = false).flatMap { _ =>
|
||||
if (maybeAlias.getOrElse("").isEmpty) Future.successful(partyId)
|
||||
else updateDescription(PartyDescription(partyId, maybeAlias)).map(_ => partyId)
|
||||
}
|
||||
}
|
||||
} {
|
||||
case Success(partyId) => redirect(s"/party/$partyId", StatusCodes.Found)
|
||||
case Failure(exception) => throw exception
|
||||
}
|
||||
}
|
||||
@ -67,6 +72,7 @@ object IndexView {
|
||||
body(
|
||||
form(action:=s"party", method:="post")(
|
||||
label("create a new party"),
|
||||
input(name:="alias", id:="alias", placeholder:="party alias", title:="alias", `type`:="text"),
|
||||
input(name:="username", id:="username", placeholder:="username", title:="username", `type`:="text"),
|
||||
input(name:="password", id:="password", placeholder:="password", title:="password", `type`:="password"),
|
||||
input(name:="add", id:="add", `type`:="submit", value:="add")
|
||||
|
@ -20,7 +20,7 @@ import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.{Failure, Success, Try}
|
||||
|
||||
class LootSuggestView(override val storage: ActorRef)(implicit timeout: Timeout)
|
||||
extends LootHelper(storage) with Authorization {
|
||||
extends LootHelper with Authorization {
|
||||
|
||||
def route: Route = getIndex ~ suggestLoot
|
||||
|
||||
|
@ -20,7 +20,7 @@ import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.Try
|
||||
|
||||
class LootView (override val storage: ActorRef)(implicit timeout: Timeout)
|
||||
extends LootHelper(storage) with Authorization {
|
||||
extends LootHelper with Authorization {
|
||||
|
||||
def route: Route = getLoot ~ modifyLoot
|
||||
|
||||
|
@ -18,8 +18,8 @@ import me.arcanis.ffxivbis.models._
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
class PlayerView(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends PlayerHelper(storage, ariyala) with Authorization {
|
||||
class PlayerView(override val storage: ActorRef, override val ariyala: ActorRef)(implicit timeout: Timeout)
|
||||
extends PlayerHelper with Authorization {
|
||||
|
||||
def route: Route = getParty ~ modifyParty
|
||||
|
||||
|
@ -16,8 +16,8 @@ import akka.util.Timeout
|
||||
|
||||
class RootView(storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout) {
|
||||
|
||||
private val basePartyView = new BasePartyView(storage)
|
||||
private val indexView = new IndexView(storage)
|
||||
private val basePartyView = new BasePartyView(storage, ariyala)
|
||||
private val indexView = new IndexView(storage, ariyala)
|
||||
|
||||
private val biSView = new BiSView(storage, ariyala)
|
||||
private val lootView = new LootView(storage)
|
||||
|
@ -20,7 +20,7 @@ import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.Try
|
||||
|
||||
class UserView(override val storage: ActorRef)(implicit timeout: Timeout)
|
||||
extends UserHelper(storage) with Authorization {
|
||||
extends UserHelper with Authorization {
|
||||
|
||||
def route: Route = getUsers ~ modifyUsers
|
||||
|
||||
|
@ -15,15 +15,15 @@ import me.arcanis.ffxivbis.service.LootSelector
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.util.Random
|
||||
|
||||
case class Party(partyId: String, rules: Seq[String], players: Map[PlayerId, Player])
|
||||
case class Party(partyDescription: PartyDescription, rules: Seq[String], players: Map[PlayerId, Player])
|
||||
extends StrictLogging {
|
||||
require(players.keys.forall(_.partyId == partyId), "party id must be same")
|
||||
require(players.keys.forall(_.partyId == partyDescription.partyId), "party id must be same")
|
||||
|
||||
def getPlayers: Seq[Player] = players.values.toSeq
|
||||
def player(playerId: PlayerId): Option[Player] = players.get(playerId)
|
||||
def withPlayer(player: Player): Party =
|
||||
try {
|
||||
require(player.partyId == partyId, "player must belong to this party")
|
||||
require(player.partyId == partyDescription.partyId, "player must belong to this party")
|
||||
copy(players = players + (player.playerId -> player))
|
||||
} catch {
|
||||
case exception: Exception =>
|
||||
@ -36,10 +36,7 @@ case class Party(partyId: String, rules: Seq[String], players: Map[PlayerId, Pla
|
||||
}
|
||||
|
||||
object Party {
|
||||
def apply(partyId: Option[String], config: Config): Party =
|
||||
new Party(partyId.getOrElse(randomPartyId), getRules(config), Map.empty)
|
||||
|
||||
def apply(partyId: String, config: Config,
|
||||
def apply(party: PartyDescription, config: Config,
|
||||
players: Map[Long, Player], bis: Seq[Loot], loot: Seq[Loot]): Party = {
|
||||
val bisByPlayer = bis.groupBy(_.playerId).view.mapValues(piece => BiS(piece.map(_.piece)))
|
||||
val lootByPlayer = loot.groupBy(_.playerId).view
|
||||
@ -49,7 +46,7 @@ object Party {
|
||||
.withBiS(bisByPlayer.get(playerId))
|
||||
.withLoot(lootByPlayer.getOrElse(playerId, Seq.empty)))
|
||||
}
|
||||
Party(partyId, getRules(config), playersWithItems)
|
||||
Party(party, getRules(config), playersWithItems)
|
||||
}
|
||||
|
||||
def getRules(config: Config): Seq[String] =
|
||||
|
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Evgeniy Alekseev.
|
||||
*
|
||||
* This file is part of ffxivbis
|
||||
* (see https://github.com/arcan1s/ffxivbis).
|
||||
*
|
||||
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package me.arcanis.ffxivbis.models
|
||||
|
||||
case class PartyDescription(partyId: String, partyAlias: Option[String]) {
|
||||
def alias: String = partyAlias.getOrElse(partyId)
|
||||
}
|
||||
|
||||
object PartyDescription {
|
||||
def empty(partyId: String): PartyDescription = PartyDescription(partyId, None)
|
||||
}
|
@ -32,10 +32,11 @@ trait Database extends Actor with StrictLogging {
|
||||
|
||||
def getParty(partyId: String, withBiS: Boolean, withLoot: Boolean): Future[Party] =
|
||||
for {
|
||||
partyDescription <- profile.getPartyDescription(partyId)
|
||||
players <- profile.getParty(partyId)
|
||||
bis <- if (withBiS) profile.getPiecesBiS(partyId) else Future(Seq.empty)
|
||||
loot <- if (withLoot) profile.getPieces(partyId) else Future(Seq.empty)
|
||||
} yield Party(partyId, context.system.settings.config, players, bis, loot)
|
||||
} yield Party(partyDescription, context.system.settings.config, players, bis, loot)
|
||||
}
|
||||
|
||||
object Database {
|
||||
|
@ -9,7 +9,7 @@
|
||||
package me.arcanis.ffxivbis.service.impl
|
||||
|
||||
import akka.pattern.pipe
|
||||
import me.arcanis.ffxivbis.models.{BiS, Player, PlayerId}
|
||||
import me.arcanis.ffxivbis.models.{BiS, PartyDescription, Player, PlayerId}
|
||||
import me.arcanis.ffxivbis.service.Database
|
||||
|
||||
import scala.concurrent.Future
|
||||
@ -26,6 +26,10 @@ trait DatabasePartyHandler { this: Database =>
|
||||
val client = sender()
|
||||
getParty(partyId, withBiS = true, withLoot = true).pipeTo(client)
|
||||
|
||||
case GetPartyDescription(partyId) =>
|
||||
val client = sender()
|
||||
profile.getPartyDescription(partyId).pipeTo(client)
|
||||
|
||||
case GetPlayer(playerId) =>
|
||||
val client = sender()
|
||||
val player = profile.getPlayerFull(playerId).flatMap { maybePlayerData =>
|
||||
@ -43,6 +47,10 @@ trait DatabasePartyHandler { this: Database =>
|
||||
case RemovePlayer(playerId) =>
|
||||
val client = sender()
|
||||
profile.deletePlayer(playerId).pipeTo(client)
|
||||
|
||||
case UpdateParty(description) =>
|
||||
val client = sender()
|
||||
profile.insertPartyDescription(description).pipeTo(client)
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,10 +59,14 @@ object DatabasePartyHandler {
|
||||
override def partyId: String = player.partyId
|
||||
}
|
||||
case class GetParty(partyId: String) extends Database.DatabaseRequest
|
||||
case class GetPartyDescription(partyId: String) extends Database.DatabaseRequest
|
||||
case class GetPlayer(playerId: PlayerId) extends Database.DatabaseRequest {
|
||||
override def partyId: String = playerId.partyId
|
||||
}
|
||||
case class RemovePlayer(playerId: PlayerId) extends Database.DatabaseRequest {
|
||||
override def partyId: String = playerId.partyId
|
||||
}
|
||||
case class UpdateParty(partyDescription: PartyDescription) extends Database.DatabaseRequest {
|
||||
override def partyId: String = partyDescription.partyId
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import slick.jdbc.JdbcProfile
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
class DatabaseProfile(context: ExecutionContext, config: Config)
|
||||
extends BiSProfile with LootProfile with PlayersProfile with UsersProfile {
|
||||
extends BiSProfile with LootProfile with PartyProfile with PlayersProfile with UsersProfile {
|
||||
|
||||
implicit val executionContext: ExecutionContext = context
|
||||
|
||||
@ -29,6 +29,7 @@ class DatabaseProfile(context: ExecutionContext, config: Config)
|
||||
|
||||
val bisTable: TableQuery[BiSPieces] = TableQuery[BiSPieces]
|
||||
val lootTable: TableQuery[LootPieces] = TableQuery[LootPieces]
|
||||
val partiesTable: TableQuery[Parties] = TableQuery[Parties]
|
||||
val playersTable: TableQuery[Players] = TableQuery[Players]
|
||||
val usersTable: TableQuery[Users] = TableQuery[Users]
|
||||
|
||||
@ -55,10 +56,10 @@ class DatabaseProfile(context: ExecutionContext, config: Config)
|
||||
private def byPartyId[T](partyId: String, callback: Seq[Long] => Future[T]): Future[T] =
|
||||
getPlayers(partyId).map(callback).flatten
|
||||
private def byPlayerId[T](playerId: PlayerId, callback: Long => Future[T]): Future[T] =
|
||||
getPlayer(playerId).map {
|
||||
getPlayer(playerId).flatMap {
|
||||
case Some(id) => callback(id)
|
||||
case None => Future.failed(new Error(s"Could not find player $playerId"))
|
||||
}.flatten
|
||||
}
|
||||
}
|
||||
|
||||
object DatabaseProfile {
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Evgeniy Alekseev.
|
||||
*
|
||||
* This file is part of ffxivbis
|
||||
* (see https://github.com/arcan1s/ffxivbis).
|
||||
*
|
||||
* License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package me.arcanis.ffxivbis.storage
|
||||
|
||||
import me.arcanis.ffxivbis.models.PartyDescription
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
trait PartyProfile { this: DatabaseProfile =>
|
||||
import dbConfig.profile.api._
|
||||
|
||||
case class PartyRep(partyId: Option[Long], partyName: String, partyAlias: Option[String]) {
|
||||
def toDescription: PartyDescription = PartyDescription(partyName, partyAlias)
|
||||
}
|
||||
object PartyRep {
|
||||
def fromDescription(party: PartyDescription, id: Option[Long]): PartyRep =
|
||||
PartyRep(id, party.partyId, party.partyAlias)
|
||||
}
|
||||
|
||||
class Parties(tag: Tag) extends Table[PartyRep](tag, "parties") {
|
||||
def partyId: Rep[Long] = column[Long]("party_id", O.AutoInc, O.PrimaryKey)
|
||||
def partyName: Rep[String] = column[String]("party_name")
|
||||
def partyAlias: Rep[Option[String]] = column[Option[String]]("party_alias")
|
||||
|
||||
def * =
|
||||
(partyId.?, partyName, partyAlias) <> ((PartyRep.apply _).tupled, PartyRep.unapply)
|
||||
}
|
||||
|
||||
def getPartyDescription(partyId: String): Future[PartyDescription] =
|
||||
db.run(partyDescription(partyId).result.headOption.map(_.map(_.toDescription).getOrElse(PartyDescription.empty(partyId))))
|
||||
def getUniquePartyId(partyId: String): Future[Option[Long]] =
|
||||
db.run(partyDescription(partyId).map(_.partyId).result.headOption)
|
||||
def insertPartyDescription(partyDescription: PartyDescription): Future[Int] =
|
||||
getUniquePartyId(partyDescription.partyId).flatMap {
|
||||
case Some(id) => db.run(partiesTable.update(PartyRep.fromDescription(partyDescription, Some(id))))
|
||||
case _ => db.run(partiesTable.insertOrUpdate(PartyRep.fromDescription(partyDescription, None)))
|
||||
}
|
||||
|
||||
|
||||
private def partyDescription(partyId: String) =
|
||||
partiesTable.filter(_.partyName === partyId)
|
||||
}
|
@ -39,7 +39,6 @@ trait PlayersProfile { this: DatabaseProfile =>
|
||||
(partyId, playerId.?, created, nick, job, bisLink, priority) <> ((PlayerRep.apply _).tupled, PlayerRep.unapply)
|
||||
}
|
||||
|
||||
|
||||
def deletePlayer(playerId: PlayerId): Future[Int] = db.run(player(playerId).delete)
|
||||
def getParty(partyId: String): Future[Map[Long, Player]] =
|
||||
db.run(players(partyId).result).map(_.foldLeft(Map.empty[Long, Player]) {
|
||||
@ -53,10 +52,10 @@ trait PlayersProfile { this: DatabaseProfile =>
|
||||
def getPlayers(partyId: String): Future[Seq[Long]] =
|
||||
db.run(players(partyId).map(_.playerId).result)
|
||||
def insertPlayer(playerObj: Player): Future[Int] =
|
||||
getPlayer(playerObj.playerId).map {
|
||||
getPlayer(playerObj.playerId).flatMap {
|
||||
case Some(id) => db.run(playersTable.update(PlayerRep.fromPlayer(playerObj, Some(id))))
|
||||
case _ => db.run(playersTable.insertOrUpdate(PlayerRep.fromPlayer(playerObj, None)))
|
||||
}.flatten
|
||||
}
|
||||
|
||||
private def player(playerId: PlayerId) =
|
||||
playersTable
|
||||
|
@ -49,10 +49,10 @@ trait UsersProfile { this: DatabaseProfile =>
|
||||
def getUsers(partyId: String): Future[Seq[User]] =
|
||||
db.run(user(partyId, None).result).map(_.map(_.toUser))
|
||||
def insertUser(userObj: User): Future[Int] =
|
||||
db.run(user(userObj.partyId, Some(userObj.username)).map(_.userId).result.headOption).map {
|
||||
db.run(user(userObj.partyId, Some(userObj.username)).map(_.userId).result.headOption).flatMap {
|
||||
case Some(id) => db.run(usersTable.insertOrUpdate(UserRep.fromUser(userObj, Some(id))))
|
||||
case _ => db.run(usersTable.insertOrUpdate(UserRep.fromUser(userObj, None)))
|
||||
}.flatten
|
||||
}
|
||||
|
||||
private def user(partyId: String, username: Option[String]) =
|
||||
usersTable
|
||||
|
@ -5,12 +5,13 @@ import akka.http.scaladsl.model.{StatusCodes, Uri}
|
||||
import akka.http.scaladsl.model.headers.{Authorization, BasicHttpCredentials}
|
||||
import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest}
|
||||
import akka.http.scaladsl.server._
|
||||
import akka.pattern.ask
|
||||
import akka.testkit.TestKit
|
||||
import akka.pattern.ask
|
||||
import com.typesafe.config.Config
|
||||
import me.arcanis.ffxivbis.{Fixtures, Settings}
|
||||
import me.arcanis.ffxivbis.http.api.v1.json._
|
||||
import me.arcanis.ffxivbis.service.{Ariyala, PartyService, impl}
|
||||
import me.arcanis.ffxivbis.models.PartyDescription
|
||||
import me.arcanis.ffxivbis.service.{Ariyala, impl}
|
||||
import me.arcanis.ffxivbis.storage.Migration
|
||||
import org.scalatest.{Matchers, WordSpec}
|
||||
|
||||
@ -23,22 +24,19 @@ class PartyEndpointTest extends WordSpec
|
||||
|
||||
private val auth: Authorization =
|
||||
Authorization(BasicHttpCredentials(Fixtures.userAdmin.username, Fixtures.userPassword))
|
||||
private val endpoint: Uri = Uri(s"/party/${Fixtures.partyId}")
|
||||
private val playerId = PlayerIdResponse.fromPlayerId(Fixtures.playerEmpty.playerId)
|
||||
private val endpoint: Uri = Uri(s"/party/${Fixtures.partyId}/description")
|
||||
private val timeout: FiniteDuration = 60 seconds
|
||||
implicit private val routeTimeout: RouteTestTimeout = RouteTestTimeout(timeout)
|
||||
|
||||
private val storage: ActorRef = system.actorOf(impl.DatabaseImpl.props)
|
||||
private val ariyala: ActorRef = system.actorOf(Ariyala.props)
|
||||
private val party: ActorRef = system.actorOf(PartyService.props(storage))
|
||||
private val route: Route = new PlayerEndpoint(party, ariyala)(timeout).route
|
||||
private val route: Route = new PartyEndpoint(storage, ariyala)(timeout).route
|
||||
|
||||
override def testConfig: Config = Settings.withRandomDatabase
|
||||
|
||||
override def beforeAll: Unit = {
|
||||
Await.result(Migration(system.settings.config), timeout)
|
||||
Await.result((storage ? impl.DatabaseUserHandler.AddUser(Fixtures.userAdmin, isHashedPassword = true))(timeout).mapTo[Int], timeout)
|
||||
Await.result((storage ? impl.DatabasePartyHandler.AddPlayer(Fixtures.playerEmpty))(timeout).mapTo[Int], timeout)
|
||||
}
|
||||
|
||||
override def afterAll: Unit = {
|
||||
@ -48,13 +46,23 @@ class PartyEndpointTest extends WordSpec
|
||||
|
||||
"api v1 party endpoint" must {
|
||||
|
||||
"get users" in {
|
||||
val uri = endpoint.withQuery(Uri.Query(Map("nick" -> playerId.nick, "job" -> playerId.job)))
|
||||
val response = Seq(PlayerResponse.fromPlayer(Fixtures.playerEmpty))
|
||||
"get empty party description" in {
|
||||
Get(endpoint).withHeaders(auth) ~> route ~> check {
|
||||
status shouldEqual StatusCodes.OK
|
||||
responseAs[PartyDescriptionResponse].toDescription shouldEqual PartyDescription.empty(Fixtures.partyId)
|
||||
}
|
||||
}
|
||||
|
||||
"update party description" in {
|
||||
val entity = PartyDescriptionResponse(Fixtures.partyId, Some("random party name"))
|
||||
|
||||
Post(endpoint, entity).withHeaders(auth) ~> route ~> check {
|
||||
status shouldEqual StatusCodes.Accepted
|
||||
}
|
||||
|
||||
Get(endpoint).withHeaders(auth) ~> route ~> check {
|
||||
status shouldEqual StatusCodes.OK
|
||||
responseAs[Seq[PlayerResponse]] shouldEqual response
|
||||
responseAs[PartyDescriptionResponse].toDescription shouldEqual entity.toDescription
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,62 @@
|
||||
package me.arcanis.ffxivbis.http.api.v1
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import akka.http.scaladsl.model.{StatusCodes, Uri}
|
||||
import akka.http.scaladsl.model.headers.{Authorization, BasicHttpCredentials}
|
||||
import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest}
|
||||
import akka.http.scaladsl.server._
|
||||
import akka.pattern.ask
|
||||
import akka.testkit.TestKit
|
||||
import com.typesafe.config.Config
|
||||
import me.arcanis.ffxivbis.{Fixtures, Settings}
|
||||
import me.arcanis.ffxivbis.http.api.v1.json._
|
||||
import me.arcanis.ffxivbis.service.{Ariyala, PartyService, impl}
|
||||
import me.arcanis.ffxivbis.storage.Migration
|
||||
import org.scalatest.{Matchers, WordSpec}
|
||||
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration._
|
||||
import scala.language.postfixOps
|
||||
|
||||
class PlayerEndpointTest extends WordSpec
|
||||
with Matchers with ScalatestRouteTest with JsonSupport {
|
||||
|
||||
private val auth: Authorization =
|
||||
Authorization(BasicHttpCredentials(Fixtures.userAdmin.username, Fixtures.userPassword))
|
||||
private val endpoint: Uri = Uri(s"/party/${Fixtures.partyId}")
|
||||
private val playerId = PlayerIdResponse.fromPlayerId(Fixtures.playerEmpty.playerId)
|
||||
private val timeout: FiniteDuration = 60 seconds
|
||||
implicit private val routeTimeout: RouteTestTimeout = RouteTestTimeout(timeout)
|
||||
|
||||
private val storage: ActorRef = system.actorOf(impl.DatabaseImpl.props)
|
||||
private val ariyala: ActorRef = system.actorOf(Ariyala.props)
|
||||
private val party: ActorRef = system.actorOf(PartyService.props(storage))
|
||||
private val route: Route = new PlayerEndpoint(party, ariyala)(timeout).route
|
||||
|
||||
override def testConfig: Config = Settings.withRandomDatabase
|
||||
|
||||
override def beforeAll: Unit = {
|
||||
Await.result(Migration(system.settings.config), timeout)
|
||||
Await.result((storage ? impl.DatabaseUserHandler.AddUser(Fixtures.userAdmin, isHashedPassword = true))(timeout).mapTo[Int], timeout)
|
||||
Await.result((storage ? impl.DatabasePartyHandler.AddPlayer(Fixtures.playerEmpty))(timeout).mapTo[Int], timeout)
|
||||
}
|
||||
|
||||
override def afterAll: Unit = {
|
||||
TestKit.shutdownActorSystem(system)
|
||||
Settings.clearDatabase(system.settings.config)
|
||||
}
|
||||
|
||||
"api v1 player endpoint" must {
|
||||
|
||||
"get users" in {
|
||||
val uri = endpoint.withQuery(Uri.Query(Map("nick" -> playerId.nick, "job" -> playerId.job)))
|
||||
val response = Seq(PlayerResponse.fromPlayer(Fixtures.playerEmpty))
|
||||
|
||||
Get(endpoint).withHeaders(auth) ~> route ~> check {
|
||||
status shouldEqual StatusCodes.OK
|
||||
responseAs[Seq[PlayerResponse]] shouldEqual response
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -6,23 +6,24 @@ import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike}
|
||||
|
||||
class PartyTest extends WordSpecLike with Matchers with BeforeAndAfterAll {
|
||||
|
||||
private val partyDescription = PartyDescription.empty(Fixtures.partyId)
|
||||
private val party =
|
||||
Party(Fixtures.partyId, Seq.empty, Map(Fixtures.playerEmpty.playerId -> Fixtures.playerEmpty))
|
||||
Party(partyDescription, Seq.empty, Map(Fixtures.playerEmpty.playerId -> Fixtures.playerEmpty))
|
||||
|
||||
"party model" must {
|
||||
|
||||
"accept player with same party id" in {
|
||||
noException should be thrownBy
|
||||
Party(Fixtures.partyId, Seq.empty, Map(Fixtures.playerEmpty.playerId -> Fixtures.playerEmpty))
|
||||
Party(partyDescription, Seq.empty, Map(Fixtures.playerEmpty.playerId -> Fixtures.playerEmpty))
|
||||
}
|
||||
|
||||
"fail on multiple party ids" in {
|
||||
val anotherPlayer = Fixtures.playerEmpty.copy(partyId = Fixtures.partyId2)
|
||||
|
||||
an [IllegalArgumentException] should be thrownBy
|
||||
Party(Fixtures.partyId, Seq.empty, Map(anotherPlayer.playerId -> anotherPlayer))
|
||||
Party(partyDescription, Seq.empty, Map(anotherPlayer.playerId -> anotherPlayer))
|
||||
an [IllegalArgumentException] should be thrownBy
|
||||
Party(Fixtures.partyId, Seq.empty, Map(Fixtures.playerEmpty.playerId -> Fixtures.playerEmpty, anotherPlayer.playerId -> anotherPlayer))
|
||||
Party(partyDescription, Seq.empty, Map(Fixtures.playerEmpty.playerId -> Fixtures.playerEmpty, anotherPlayer.playerId -> anotherPlayer))
|
||||
}
|
||||
|
||||
"return player list" in {
|
||||
@ -38,7 +39,7 @@ class PartyTest extends WordSpecLike with Matchers with BeforeAndAfterAll {
|
||||
}
|
||||
|
||||
"add new player" in {
|
||||
val newParty = Party(Fixtures.partyId, Seq.empty, Map.empty)
|
||||
val newParty = Party(partyDescription, Seq.empty, Map.empty)
|
||||
newParty.withPlayer(Fixtures.playerEmpty) shouldEqual party
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ class LootSelectorTest extends TestKit(ActorSystem("lootselector"))
|
||||
|
||||
import me.arcanis.ffxivbis.utils.Converters._
|
||||
|
||||
private var default: Party = Party(Some(Fixtures.partyId), Settings.config(Map.empty))
|
||||
private var default: Party = Party(PartyDescription.empty(Fixtures.partyId), Settings.config(Map.empty), Map.empty, Seq.empty, Seq.empty)
|
||||
private var dnc: Player = Player(-1, Fixtures.partyId, Job.DNC, "a nick", BiS(), Seq.empty, Some(Fixtures.link))
|
||||
private var drg: Player = Player(-1, Fixtures.partyId, Job.DRG, "another nick", BiS(), Seq.empty, Some(Fixtures.link2))
|
||||
private val timeout: FiniteDuration = 60 seconds
|
||||
|
Loading…
Reference in New Issue
Block a user