multi item support

This commit is contained in:
Evgenii Alekseev 2020-12-03 03:35:06 +03:00
parent 25b05aa289
commit 2e16a8c1fa
24 changed files with 195 additions and 85 deletions

View File

@ -0,0 +1,2 @@
drop index bis_piece_player_id_idx;
create index bis_piece_type_player_id_idx on bis(player_id, piece, piece_type);

View File

@ -0,0 +1,2 @@
drop index bis_piece_player_id_idx;
create index bis_piece_type_player_id_idx on bis(player_id, piece, piece_type);

View File

@ -37,10 +37,13 @@ trait BiSHelper extends BisProviderHelper {
}
def putBiS(playerId: PlayerId, link: String)
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] =
downloadBiS(link, playerId.job).flatMap { bis =>
Future.traverse(bis.pieces)(addPieceBiS(playerId, _))
}.map(_ => ())
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] = {
(storage ? DatabaseBiSHandler.RemovePiecesFromBiS(playerId)).flatMap { _ =>
downloadBiS(link, playerId.job).flatMap { bis =>
Future.traverse(bis.pieces)(addPieceBiS(playerId, _))
}.map(_ => ())
}
}
def removePieceBiS(playerId: PlayerId, piece: Piece)
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] =

View File

@ -21,13 +21,15 @@ case class PlayerResponse(
@Schema(description = "player loot priority", `type` = "number") priority: Option[Int]) {
def toPlayer: Player =
Player(-1, partyId, Job.withName(job), nick,
BiS(bis.getOrElse(Seq.empty).map(_.toPiece)), loot.getOrElse(Seq.empty).map(_.toLoot),
BiS(bis.getOrElse(Seq.empty).map(_.toPiece)),
loot.getOrElse(Seq.empty).map(_.toLoot),
link, priority.getOrElse(0))
}
object PlayerResponse {
def fromPlayer(player: Player): PlayerResponse =
PlayerResponse(player.partyId, player.job.toString, player.nick,
Some(player.bis.pieces.map(PieceResponse.fromPiece)), Some(player.loot.map(LootResponse.fromLoot)),
Some(player.bis.pieces.map(PieceResponse.fromPiece)),
Some(player.loot.map(LootResponse.fromLoot)),
player.link, Some(player.priority))
}

View File

@ -113,7 +113,7 @@ object BiSView {
input(name:="add", id:="add", `type`:="submit", value:="add")
),
form(action:="/bis", method:="post")(
form(action:=s"/party/$partyId/bis", method:="post")(
select(name:="player", id:="player", title:="player")
(for (player <- party) yield option(player.playerId.toString)),
input(name:="link", id:="link", placeholder:="player bis link", title:="link", `type`:="text"),

View File

@ -47,8 +47,8 @@ class PlayerView(override val storage: ActorRef, override val ariyala: ActorRef)
post {
formFields("nick".as[String], "job".as[String], "priority".as[Int].?, "link".as[String].?, "action".as[String]) {
(nick, job, maybePriority, maybeLink, action) =>
onComplete(modifyPartyCall(partyId, nick, job, maybePriority, maybeLink, action)) {
case _ => redirect(s"/party/$partyId/players", StatusCodes.Found)
onComplete(modifyPartyCall(partyId, nick, job, maybePriority, maybeLink, action)) { _ =>
redirect(s"/party/$partyId/players", StatusCodes.Found)
}
}
}
@ -62,7 +62,7 @@ class PlayerView(override val storage: ActorRef, override val ariyala: ActorRef)
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] = {
def maybePlayerId = PlayerId(partyId, Some(nick), Some(job))
def player(playerId: PlayerId) =
Player(-1, partyId, playerId.job, playerId.nick, BiS(), Seq.empty, maybeLink, maybePriority.getOrElse(0))
Player(-1, partyId, playerId.job, playerId.nick, BiS.empty, Seq.empty, maybeLink, maybePriority.getOrElse(0))
(action, maybePlayerId) match {
case ("add", Some(playerId)) => addPlayer(player(playerId)).map(_ => ())

View File

@ -8,21 +8,7 @@
*/
package me.arcanis.ffxivbis.models
case class BiS(weapon: Option[Piece],
head: Option[Piece],
body: Option[Piece],
hands: Option[Piece],
waist: Option[Piece],
legs: Option[Piece],
feet: Option[Piece],
ears: Option[Piece],
neck: Option[Piece],
wrist: Option[Piece],
leftRing: Option[Piece],
rightRing: Option[Piece]) {
val pieces: Seq[Piece] =
Seq(weapon, head, body, hands, waist, legs, feet, ears, neck, wrist, leftRing, rightRing).flatten
case class BiS(pieces: Seq[Piece]) {
def hasPiece(piece: Piece): Boolean = piece match {
case upgrade: PieceUpgrade => upgrades.contains(upgrade)
@ -31,50 +17,27 @@ case class BiS(weapon: Option[Piece],
def upgrades: Map[PieceUpgrade, Int] =
pieces.groupBy(_.upgrade).foldLeft(Map.empty[PieceUpgrade, Int]) {
case (acc, (Some(k), v)) => acc + (k -> v.length)
case (acc, (Some(k), v)) => acc + (k -> v.size)
case (acc, _) => acc
} withDefaultValue 0
def withPiece(piece: Piece): BiS = copyWithPiece(piece.piece, Some(piece))
def withoutPiece(piece: Piece): BiS = copyWithPiece(piece.piece, None)
def withPiece(piece: Piece): BiS = copy(pieces :+ piece)
def withoutPiece(piece: Piece): BiS = copy(pieces.filterNot(_.strictEqual(piece)))
private def copyWithPiece(name: String, piece: Option[Piece]): BiS = {
val params = Map(
"weapon" -> weapon,
"head" -> head,
"body" -> body,
"hands" -> hands,
"waist" -> waist,
"legs" -> legs,
"feet" -> feet,
"ears" -> ears,
"neck" -> neck,
"wrist" -> wrist,
"left ring" -> leftRing,
"right ring" -> rightRing
) + (name -> piece)
BiS(params)
override def equals(obj: Any): Boolean = {
def comparePieces(left: Seq[Piece], right: Seq[Piece]): Boolean =
left.groupBy(identity).view.mapValues(_.size).forall {
case (key, count) => right.count(_.strictEqual(key)) == count
}
obj match {
case left: BiS => comparePieces(left.pieces, pieces)
case _ => false
}
}
}
object BiS {
def apply(data: Map[String, Option[Piece]]): BiS =
BiS(
data.get("weapon").flatten,
data.get("head").flatten,
data.get("body").flatten,
data.get("hands").flatten,
data.get("waist").flatten,
data.get("legs").flatten,
data.get("feet").flatten,
data.get("ears").flatten,
data.get("neck").flatten,
data.get("wrist").flatten,
data.get("left ring").flatten,
data.get("right ring").flatten)
def apply(): BiS = BiS(Seq.empty)
def apply(pieces: Seq[Piece]): BiS =
BiS(pieces.map(piece => piece.piece -> Some(piece)).toMap)
def empty: BiS = BiS(Seq.empty)
}

View File

@ -9,6 +9,7 @@
package me.arcanis.ffxivbis.models
object Job {
sealed trait RightSide
object AccessoriesDex extends RightSide
object AccessoriesInt extends RightSide
@ -26,6 +27,7 @@ object Job {
object BodyRanges extends LeftSide
sealed trait Job {
def leftSide: LeftSide
def rightSide: RightSide

View File

@ -11,5 +11,6 @@ package me.arcanis.ffxivbis.models
import java.time.Instant
case class Loot(playerId: Long, piece: Piece, timestamp: Instant, isFreeLoot: Boolean) {
def isFreeLootToString: String = if (isFreeLoot) "yes" else "no"
}

View File

@ -36,6 +36,7 @@ case class Party(partyDescription: PartyDescription, rules: Seq[String], players
}
object Party {
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)))

View File

@ -9,9 +9,11 @@
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)
}

View File

@ -8,7 +8,8 @@
*/
package me.arcanis.ffxivbis.models
sealed trait Piece {
sealed trait Piece extends Equals {
def pieceType: PieceType.PieceType
def job: Job.Job
def piece: String
@ -22,6 +23,9 @@ sealed trait Piece {
case _: PieceBody => Some(BodyUpgrade)
case _: PieceWeapon => Some(WeaponUpgrade)
}
// used for ring comparison
def strictEqual(obj: Any): Boolean = equals(obj)
}
trait PieceAccessory extends Piece
@ -78,10 +82,16 @@ case class Wrist(override val pieceType: PieceType.PieceType, override val job:
case class Ring(override val pieceType: PieceType.PieceType, override val job: Job.Job, override val piece: String = "ring")
extends PieceAccessory {
def withJob(other: Job.Job): Piece = copy(job = other)
override def equals(obj: Any): Boolean = obj match {
case Ring(thatPieceType, thatJob, _) => (thatPieceType == pieceType) && (thatJob == job)
case _ => false
}
override def strictEqual(obj: Any): Boolean = obj match {
case ring: Ring => equals(obj) && (ring.piece == this.piece)
case _ => false
}
}
case object AccessoryUpgrade extends PieceUpgrade {

View File

@ -1,6 +1,7 @@
package me.arcanis.ffxivbis.models
object PieceType {
sealed trait PieceType
case object Crafted extends PieceType

View File

@ -12,6 +12,7 @@ import scala.util.Try
import scala.util.matching.Regex
trait PlayerIdBase {
def job: Job.Job
def nick: String
@ -21,6 +22,7 @@ trait PlayerIdBase {
case class PlayerId(partyId: String, job: Job.Job, nick: String) extends PlayerIdBase
object PlayerId {
def apply(partyId: String, maybeNick: Option[String], maybeJob: Option[String]): Option[PlayerId] =
(maybeNick, maybeJob) match {
case (Some(nick), Some(job)) => Try(PlayerId(partyId, Job.withName(job), nick)).toOption

View File

@ -38,6 +38,7 @@ case class PlayerIdWithCounters(partyId: String,
}
object PlayerIdWithCounters {
private case class PlayerCountersComparator(values: Int*) {
def >(that: PlayerCountersComparator): Boolean = {
@scala.annotation.tailrec

View File

@ -29,6 +29,10 @@ trait DatabaseBiSHandler { this: Database =>
case RemovePieceFromBiS(playerId, piece) =>
val client = sender()
profile.deletePieceBiS(playerId, piece).pipeTo(client)
case RemovePiecesFromBiS(playerId) =>
val client = sender()
profile.deletePiecesBiS(playerId).pipeTo(client)
}
}
@ -40,4 +44,7 @@ object DatabaseBiSHandler {
case class RemovePieceFromBiS(playerId: PlayerId, piece: Piece) extends Database.DatabaseRequest {
override def partyId: String = playerId.partyId
}
case class RemovePiecesFromBiS(playerId: PlayerId) extends Database.DatabaseRequest {
override def partyId: String = playerId.partyId
}
}

View File

@ -46,14 +46,21 @@ trait BiSProfile { this: DatabaseProfile =>
def deletePieceBiSById(piece: Piece)(playerId: Long): Future[Int] =
db.run(pieceBiS(BiSRep.fromPiece(playerId, piece)).delete)
def deletePiecesBiSById(playerId: Long): Future[Int] =
db.run(piecesBiS(Seq(playerId)).delete)
def getPiecesBiSById(playerId: Long): Future[Seq[Loot]] = getPiecesBiSById(Seq(playerId))
def getPiecesBiSById(playerIds: Seq[Long]): Future[Seq[Loot]] =
db.run(piecesBiS(playerIds).result).map(_.map(_.toLoot))
def insertPieceBiSById(piece: Piece)(playerId: Long): Future[Int] =
db.run(bisTable.insertOrUpdate(BiSRep.fromPiece(playerId, piece)))
getPiecesBiSById(playerId).flatMap {
case pieces if pieces.exists(loot => loot.piece.strictEqual(piece)) => Future.successful(0)
case _ => db.run(bisTable.insertOrUpdate(BiSRep.fromPiece(playerId, piece)))
}
private def pieceBiS(piece: BiSRep) =
piecesBiS(Seq(piece.playerId)).filter(_.piece === piece.piece)
piecesBiS(Seq(piece.playerId)).filter { stored =>
(stored.piece === piece.piece) && (stored.pieceType === piece.pieceType)
}
private def piecesBiS(playerIds: Seq[Long]) =
bisTable.filter(_.playerId.inSet(playerIds.toSet))
}

View File

@ -36,6 +36,8 @@ class DatabaseProfile(context: ExecutionContext, config: Config)
// generic bis api
def deletePieceBiS(playerId: PlayerId, piece: Piece): Future[Int] =
byPlayerId(playerId, deletePieceBiSById(piece))
def deletePiecesBiS(playerId: PlayerId): Future[Int] =
byPlayerId(playerId, deletePiecesBiSById)
def getPiecesBiS(playerId: PlayerId): Future[Seq[Loot]] =
byPlayerId(playerId, getPiecesBiSById)
def getPiecesBiS(partyId: String): Future[Seq[Loot]] =
@ -57,7 +59,7 @@ class DatabaseProfile(context: ExecutionContext, config: Config)
byPlayerId(playerId, insertPieceById(loot))
private def byPartyId[T](partyId: String, callback: Seq[Long] => Future[T]): Future[T] =
getPlayers(partyId).map(callback).flatten
getPlayers(partyId).flatMap(callback)
private def byPlayerId[T](playerId: PlayerId, callback: Long => Future[T]): Future[T] =
getPlayer(playerId).flatMap {
case Some(id) => callback(id)

View File

@ -19,7 +19,7 @@ trait PlayersProfile { this: DatabaseProfile =>
nick: String, job: String, link: Option[String], priority: Int) {
def toPlayer: Player =
Player(playerId.getOrElse(-1), partyId, Job.withName(job), nick,
BiS(Seq.empty), List.empty, link, priority)
BiS.empty, Seq.empty, link, priority)
}
object PlayerRep {
def fromPlayer(player: Player, id: Option[Long]): PlayerRep =

View File

@ -26,6 +26,7 @@ object Fixtures {
lazy val lootWeapon: Piece = Weapon(pieceType = PieceType.Tome, Job.AnyJob)
lazy val lootBody: Piece = Body(pieceType = PieceType.Savage, Job.AnyJob)
lazy val lootBodyCrafted: Piece = Body(pieceType = PieceType.Crafted, Job.AnyJob)
lazy val lootHands: Piece = Hands(pieceType = PieceType.Tome, Job.AnyJob)
lazy val lootWaist: Piece = Waist(pieceType = PieceType.Tome, Job.AnyJob)
lazy val lootLegs: Piece = Legs(pieceType = PieceType.Savage, Job.AnyJob)
@ -40,7 +41,7 @@ object Fixtures {
lazy val partyId2: String = Party.randomPartyId
lazy val playerEmpty: Player =
Player(1, partyId, Job.DNC, "Siuan Sanche", BiS(), Seq.empty, Some(link))
Player(1, partyId, Job.DNC, "Siuan Sanche", BiS.empty, Seq.empty, Some(link))
lazy val playerWithBiS: Player = playerEmpty.copy(bis = bis)
lazy val userPassword: String = "password"

View File

@ -10,10 +10,11 @@ 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.models.BiS
import me.arcanis.ffxivbis.models.{BiS, Body, Job, PieceType}
import me.arcanis.ffxivbis.service.bis.BisProvider
import me.arcanis.ffxivbis.service.{PartyService, impl}
import me.arcanis.ffxivbis.storage.Migration
import me.arcanis.ffxivbis.utils.Compare
import org.scalatest.{Matchers, WordSpec}
import scala.concurrent.Await
@ -48,6 +49,15 @@ class BiSEndpointTest extends WordSpec
Settings.clearDatabase(system.settings.config)
}
private def compareBiSResponse(actual: PlayerResponse, expected: PlayerResponse): Unit = {
actual.partyId shouldEqual expected.partyId
actual.nick shouldEqual expected.nick
actual.job shouldEqual expected.job
Compare.seqEquals(actual.bis.get, expected.bis.get) shouldEqual true
actual.link shouldEqual expected.link
actual.priority shouldEqual expected.priority
}
"api v1 bis endpoint" must {
"create best in slot set from ariyala" in {
@ -61,11 +71,13 @@ class BiSEndpointTest extends WordSpec
"return best in slot set" in {
val uri = endpoint.withQuery(Uri.Query(Map("nick" -> playerId.nick, "job" -> playerId.job)))
val response = Seq(PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(Fixtures.bis))))
val response = PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(Fixtures.bis)))
Get(uri).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.OK
responseAs[Seq[PlayerResponse]] shouldEqual response
val actual = responseAs[Seq[PlayerResponse]]
actual.length shouldEqual 1
actual.foreach(compareBiSResponse(_, response))
}
}
@ -80,11 +92,13 @@ class BiSEndpointTest extends WordSpec
val uri = endpoint.withQuery(Uri.Query(Map("nick" -> playerId.nick, "job" -> playerId.job)))
val bis = BiS(Fixtures.bis.pieces.filterNot(_ == Fixtures.lootBody))
val response = Seq(PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(bis))))
val response = PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(bis)))
Get(uri).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.OK
responseAs[Seq[PlayerResponse]] shouldEqual response
val actual = responseAs[Seq[PlayerResponse]]
actual.length shouldEqual 1
actual.foreach(compareBiSResponse(_, response))
}
}
@ -98,11 +112,102 @@ class BiSEndpointTest extends WordSpec
}
val uri = endpoint.withQuery(Uri.Query(Map("nick" -> playerId.nick, "job" -> playerId.job)))
val response = Seq(PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(Fixtures.bis))))
val response = PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(Fixtures.bis)))
Get(uri).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.OK
responseAs[Seq[PlayerResponse]] shouldEqual response
val actual = responseAs[Seq[PlayerResponse]]
actual.length shouldEqual 1
actual.foreach(compareBiSResponse(_, response))
}
}
"do not allow to add same item to best in slot set" in {
val piece = PieceResponse.fromPiece(Fixtures.lootBody.withJob(Job.DNC))
val entity = PieceActionResponse(ApiAction.add, piece, playerId, None)
Post(endpoint, entity).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.Accepted
responseAs[String] shouldEqual ""
}
val uri = endpoint.withQuery(Uri.Query(Map("nick" -> playerId.nick, "job" -> playerId.job)))
val response = PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(Fixtures.bis)))
Get(uri).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.OK
val actual = responseAs[Seq[PlayerResponse]]
actual.length shouldEqual 1
actual.foreach(compareBiSResponse(_, response))
}
}
"allow to add item with another type to best in slot set" in {
val piece = PieceResponse.fromPiece(Fixtures.lootBodyCrafted.withJob(Job.DNC))
val entity = PieceActionResponse(ApiAction.add, piece, playerId, None)
Post(endpoint, entity).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.Accepted
responseAs[String] shouldEqual ""
}
val uri = endpoint.withQuery(Uri.Query(Map("nick" -> playerId.nick, "job" -> playerId.job)))
val bis = Fixtures.bis.withPiece(piece.toPiece)
val response = PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(bis)))
Get(uri).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.OK
val actual = responseAs[Seq[PlayerResponse]]
actual.length shouldEqual 1
actual.foreach(compareBiSResponse(_, response))
}
}
"remove only specific item from best in slot set" in {
val piece = PieceResponse.fromPiece(Fixtures.lootBodyCrafted.withJob(Job.DNC))
val entity = PieceActionResponse(ApiAction.remove, piece, playerId, None)
Post(endpoint, entity).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.Accepted
responseAs[String] shouldEqual ""
}
val uri = endpoint.withQuery(Uri.Query(Map("nick" -> playerId.nick, "job" -> playerId.job)))
val response = PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(Fixtures.bis)))
Get(uri).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.OK
val actual = responseAs[Seq[PlayerResponse]]
actual.length shouldEqual 1
actual.foreach(compareBiSResponse(_, response))
}
}
"totaly replace player bis" in {
// add random item first
val piece = PieceResponse.fromPiece(Fixtures.lootBodyCrafted.withJob(Job.DNC))
val entity = PieceActionResponse(ApiAction.add, piece, playerId, None)
Post(endpoint, entity).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.Accepted
responseAs[String] shouldEqual ""
}
val bisEntity = PlayerBiSLinkResponse(Fixtures.link, playerId)
Put(endpoint, bisEntity).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.Created
responseAs[String] shouldEqual ""
}
val uri = endpoint.withQuery(Uri.Query(Map("nick" -> playerId.nick, "job" -> playerId.job)))
val response = PlayerResponse.fromPlayer(Fixtures.playerEmpty.withBiS(Some(Fixtures.bis)))
Get(uri).withHeaders(auth) ~> route ~> check {
status shouldEqual StatusCodes.OK
val actual = responseAs[Seq[PlayerResponse]]
actual.length shouldEqual 1
actual.foreach(compareBiSResponse(_, response))
}
}

View File

@ -29,18 +29,14 @@ class BiSTest extends WordSpecLike with Matchers with BeforeAndAfterAll {
val bis = BiS(Seq(Fixtures.lootLegs))
val newBis = bis.withPiece(Fixtures.lootHands)
newBis.legs shouldEqual Some(Fixtures.lootLegs)
newBis.hands shouldEqual Some(Fixtures.lootHands)
newBis.pieces.length shouldEqual 2
newBis shouldEqual BiS(Seq(Fixtures.lootLegs, Fixtures.lootHands))
}
"create copy without piece" in {
val bis = BiS(Seq(Fixtures.lootHands, Fixtures.lootLegs))
val newBis = bis.withoutPiece(Fixtures.lootHands)
newBis.legs shouldEqual Some(Fixtures.lootLegs)
newBis.hands shouldEqual None
newBis.pieces.length shouldEqual 1
newBis shouldEqual BiS(Seq(Fixtures.lootLegs))
}
"ignore upgrade on modification" in {

View File

@ -72,7 +72,7 @@ class DatabaseBiSHandlerTest
database ! impl.DatabaseBiSHandler.GetBiS(Fixtures.playerEmpty.partyId, None)
expectMsgPF(timeout) {
case party: Seq[_] if partyBiSCompare(party, Seq(newPiece)) => ()
case party: Seq[_] if partyBiSCompare(party, Seq(Fixtures.lootHands, newPiece)) => ()
}
}

View File

@ -18,8 +18,8 @@ class LootSelectorTest extends TestKit(ActorSystem("lootselector"))
import me.arcanis.ffxivbis.utils.Converters._
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 var dnc: Player = Player(-1, Fixtures.partyId, Job.DNC, "a nick", BiS.empty, Seq.empty, Some(Fixtures.link))
private var drg: Player = Player(-1, Fixtures.partyId, Job.DRG, "another nick", BiS.empty, Seq.empty, Some(Fixtures.link2))
private val timeout: FiniteDuration = 60 seconds
override def beforeAll(): Unit = {
@ -51,7 +51,7 @@ class LootSelectorTest extends TestKit(ActorSystem("lootselector"))
"suggest upgrade" in {
val party = default.withPlayer(
dnc.withBiS(
Some(dnc.bis.copy(weapon = Some(Weapon(pieceType = PieceType.Tome, Job.DNC))))
Some(dnc.bis.withPiece(Weapon(pieceType = PieceType.Tome, Job.DNC)))
)
)