From 4cdcd80d519c59803edee36238eaca6ee0f72eac Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Sat, 26 Oct 2019 19:44:51 +0300 Subject: [PATCH] more tests --- src/main/resources/html/bis.html | 0 .../arcanis/ffxivbis/http/PlayerHelper.scala | 3 +- .../http/api/v1/json/PieceResponse.scala | 2 +- .../http/api/v1/json/PlayerIdResponse.scala | 2 +- .../http/api/v1/json/PlayerResponse.scala | 2 +- .../ffxivbis/http/view/IndexView.scala | 3 +- .../ffxivbis/http/view/PlayerView.scala | 2 +- .../me/arcanis/ffxivbis/models/BiS.scala | 2 +- .../me/arcanis/ffxivbis/models/Job.scala | 142 +++++++++++------- .../ffxivbis/{service => models}/Party.scala | 17 ++- .../me/arcanis/ffxivbis/models/Piece.scala | 2 +- .../me/arcanis/ffxivbis/models/Player.scala | 2 +- .../me/arcanis/ffxivbis/models/PlayerId.scala | 4 +- .../arcanis/ffxivbis/service/Database.scala | 2 +- .../arcanis/ffxivbis/storage/BiSProfile.scala | 2 +- .../ffxivbis/storage/LootProfile.scala | 2 +- .../ffxivbis/storage/PlayersProfile.scala | 2 +- .../me/arcanis/ffxivbis/models/BiSTest.scala | 55 +++++++ .../me/arcanis/ffxivbis/models/Fixtures.scala | 14 +- .../me/arcanis/ffxivbis/models/JobTest.scala | 26 ++++ .../arcanis/ffxivbis/models/PartyTest.scala | 51 +++++++ .../arcanis/ffxivbis/models/PieceTest.scala | 32 ++++ .../ffxivbis/models/PlayerIdTest.scala | 14 ++ .../arcanis/ffxivbis/models/PlayerTest.scala | 18 +++ .../me/arcanis/ffxivbis/models/UserTest.scala | 24 +++ .../service/DatabasePartyHandlerTest.scala | 2 +- .../me/arcanis/ffxivbis/utils/Compare.scala | 5 + 27 files changed, 345 insertions(+), 87 deletions(-) delete mode 100644 src/main/resources/html/bis.html rename src/main/scala/me/arcanis/ffxivbis/{service => models}/Party.scala (79%) create mode 100644 src/test/scala/me/arcanis/ffxivbis/models/BiSTest.scala create mode 100644 src/test/scala/me/arcanis/ffxivbis/models/JobTest.scala create mode 100644 src/test/scala/me/arcanis/ffxivbis/models/PartyTest.scala create mode 100644 src/test/scala/me/arcanis/ffxivbis/models/PieceTest.scala create mode 100644 src/test/scala/me/arcanis/ffxivbis/models/PlayerIdTest.scala create mode 100644 src/test/scala/me/arcanis/ffxivbis/models/PlayerTest.scala create mode 100644 src/test/scala/me/arcanis/ffxivbis/models/UserTest.scala diff --git a/src/main/resources/html/bis.html b/src/main/resources/html/bis.html deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/scala/me/arcanis/ffxivbis/http/PlayerHelper.scala b/src/main/scala/me/arcanis/ffxivbis/http/PlayerHelper.scala index 50dfc46..85e46cf 100644 --- a/src/main/scala/me/arcanis/ffxivbis/http/PlayerHelper.scala +++ b/src/main/scala/me/arcanis/ffxivbis/http/PlayerHelper.scala @@ -11,8 +11,7 @@ package me.arcanis.ffxivbis.http import akka.actor.ActorRef import akka.pattern.ask import akka.util.Timeout -import me.arcanis.ffxivbis.models.{Player, PlayerId} -import me.arcanis.ffxivbis.service.Party +import me.arcanis.ffxivbis.models.{Party, Player, PlayerId} import me.arcanis.ffxivbis.service.impl.{DatabaseBiSHandler, DatabasePartyHandler} import scala.concurrent.{ExecutionContext, Future} diff --git a/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PieceResponse.scala b/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PieceResponse.scala index f4aa9f7..65ebfe5 100644 --- a/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PieceResponse.scala +++ b/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PieceResponse.scala @@ -15,7 +15,7 @@ case class PieceResponse( @Schema(description = "is piece tome gear", required = true) isTome: Boolean, @Schema(description = "job name to which piece belong or AnyJob", required = true, example = "DNC") job: String, @Schema(description = "piece name", required = true, example = "body") piece: String) { - def toPiece: Piece = Piece(piece, isTome, Job.fromString(job)) + def toPiece: Piece = Piece(piece, isTome, Job.withName(job)) } object PieceResponse { diff --git a/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PlayerIdResponse.scala b/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PlayerIdResponse.scala index f6a9202..0dc3353 100644 --- a/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PlayerIdResponse.scala +++ b/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PlayerIdResponse.scala @@ -16,5 +16,5 @@ case class PlayerIdResponse( @Schema(description = "job name", required = true, example = "DNC") job: String, @Schema(description = "player nick name", required = true, example = "Siuan Sanche") nick: String) { def withPartyId(partyId: String): PlayerId = - PlayerId(partyId, Job.fromString(job), nick) + PlayerId(partyId, Job.withName(job), nick) } diff --git a/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PlayerResponse.scala b/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PlayerResponse.scala index d993ef9..54b2db6 100644 --- a/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PlayerResponse.scala +++ b/src/main/scala/me/arcanis/ffxivbis/http/api/v1/json/PlayerResponse.scala @@ -20,7 +20,7 @@ case class PlayerResponse( @Schema(description = "link to best in slot", example = "https://ffxiv.ariyala.com/19V5R") link: Option[String], @Schema(description = "player loot priority") priority: Option[Int]) { def toPlayer: Player = - Player(partyId, Job.fromString(job), nick, + Player(partyId, Job.withName(job), nick, BiS(bis.getOrElse(Seq.empty).map(_.toPiece)), loot.getOrElse(Seq.empty).map(_.toPiece), link, priority.getOrElse(0)) } diff --git a/src/main/scala/me/arcanis/ffxivbis/http/view/IndexView.scala b/src/main/scala/me/arcanis/ffxivbis/http/view/IndexView.scala index 5399b9f..1c52c2f 100644 --- a/src/main/scala/me/arcanis/ffxivbis/http/view/IndexView.scala +++ b/src/main/scala/me/arcanis/ffxivbis/http/view/IndexView.scala @@ -14,8 +14,7 @@ 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.service.Party +import me.arcanis.ffxivbis.models.{Party, Permission, User} class IndexView(storage: ActorRef)(implicit timeout: Timeout) extends UserHelper(storage) { diff --git a/src/main/scala/me/arcanis/ffxivbis/http/view/PlayerView.scala b/src/main/scala/me/arcanis/ffxivbis/http/view/PlayerView.scala index bad264b..b7e8bd9 100644 --- a/src/main/scala/me/arcanis/ffxivbis/http/view/PlayerView.scala +++ b/src/main/scala/me/arcanis/ffxivbis/http/view/PlayerView.scala @@ -92,7 +92,7 @@ object PlayerView { form(action:=s"/party/$partyId/players", method:="post")( input(name:="nick", id:="nick", placeholder:="nick", title:="nick", `type`:="nick"), select(name:="job", id:="job", title:="job") - (for (job <- Job.groupAll) yield option(job.toString)), + (for (job <- Job.jobs) yield option(job.toString)), input(name:="link", id:="link", placeholder:="player bis link", title:="link", `type`:="text"), input(name:="prioiry", id:="priority", placeholder:="priority", title:="priority", `type`:="number", value:="0"), input(name:="action", id:="action", `type`:="hidden", value:="add"), diff --git a/src/main/scala/me/arcanis/ffxivbis/models/BiS.scala b/src/main/scala/me/arcanis/ffxivbis/models/BiS.scala index 7ed3570..38dc7d8 100644 --- a/src/main/scala/me/arcanis/ffxivbis/models/BiS.scala +++ b/src/main/scala/me/arcanis/ffxivbis/models/BiS.scala @@ -76,5 +76,5 @@ object BiS { def apply(): BiS = BiS(Seq.empty) def apply(pieces: Seq[Piece]): BiS = - BiS(pieces.map { piece => piece.piece -> Some(piece) }.toMap) + BiS(pieces.map(piece => piece.piece -> Some(piece)).toMap) } diff --git a/src/main/scala/me/arcanis/ffxivbis/models/Job.scala b/src/main/scala/me/arcanis/ffxivbis/models/Job.scala index 01c68e7..beaae30 100644 --- a/src/main/scala/me/arcanis/ffxivbis/models/Job.scala +++ b/src/main/scala/me/arcanis/ffxivbis/models/Job.scala @@ -9,65 +9,95 @@ package me.arcanis.ffxivbis.models object Job { - sealed trait Job + sealed trait RightSide + object AccessoriesDex extends RightSide + object AccessoriesInt extends RightSide + object AccessoriesMnd extends RightSide + object AccessoriesStr extends RightSide + object AccessoriesVit extends RightSide + + sealed trait LeftSide + object BodyCasters extends LeftSide + object BodyDrgs extends LeftSide + object BodyHealers extends LeftSide + object BodyMnks extends LeftSide + object BodyNins extends LeftSide + object BodyTanks extends LeftSide + object BodyRanges extends LeftSide + + sealed trait Job { + def leftSide: LeftSide + def rightSide: RightSide + + // conversion to string to avoid recursion + override def equals(obj: Any): Boolean = { + def canEqual(obj: Any): Boolean = obj.isInstanceOf[Job] + def equality(objRepr: String): Boolean = objRepr match { + case _ if objRepr == AnyJob.toString => true + case _ if this.toString == AnyJob.toString => true + case _ => this.toString == obj.toString + } + + canEqual(obj) && equality(obj.toString) + } + } case object AnyJob extends Job { - override def equals(obj: Any): Boolean = obj match { - case Job => true - case _ => false - } + val leftSide: LeftSide = null + val rightSide: RightSide = null } - case object PLD extends Job - case object WAR extends Job - case object DRK extends Job - case object GNB extends Job - - case object WHM extends Job - case object SCH extends Job - case object AST extends Job - - case object MNK extends Job - case object DRG extends Job - case object NIN extends Job - case object SAM extends Job - - case object BRD extends Job - case object MCH extends Job - case object DNC extends Job - - case object BLM extends Job - case object SMN extends Job - case object RDM extends Job - - def groupAccessoriesDex: Seq[Job.Job] = groupRanges :+ NIN - def groupAccessoriesStr: Seq[Job.Job] = groupMnk :+ DRG - def groupAll: Seq[Job.Job] = groupCasters ++ groupHealers ++ groupRanges ++ groupTanks - def groupCasters: Seq[Job.Job] = Seq(BLM, SMN, RDM) - def groupHealers: Seq[Job.Job] = Seq(WHM, SCH, AST) - def groupMnk: Seq[Job.Job] = Seq(MNK, SAM) - def groupRanges: Seq[Job.Job] = Seq(BRD, MCH, DNC) - def groupTanks: Seq[Job.Job] = Seq(PLD, WAR, DRK, GNB) - - def groupFull: Seq[Seq[Job.Job]] = Seq(groupCasters, groupHealers, groupMnk, groupRanges, groupTanks) - def groupRight: Seq[Seq[Job.Job]] = Seq(groupAccessoriesDex, groupAccessoriesStr) - - def fromString(job: String): Job.Job = groupAll.find(_.toString == job.toUpperCase).orNull - - def hasSameLoot(left: Job, right: Job, piece: Piece): Boolean = { - def isAccessory(piece: Piece): Boolean = piece match { - case _: PieceAccessory => true - case _ => false - } - def isWeapon(piece: Piece): Boolean = piece match { - case _: PieceWeapon => true - case _ => false - } - - if (left == right) true - else if (isWeapon(piece)) false - else if (groupFull.exists(group => group.contains(left) && group.contains(right))) true - else if (isAccessory(piece) && groupRight.exists(group => group.contains(left) && group.contains(right))) true - else false + trait Casters extends Job { + val leftSide: LeftSide = BodyCasters + val rightSide: RightSide = AccessoriesInt } + trait Healers extends Job { + val leftSide: LeftSide = BodyHealers + val rightSide: RightSide = AccessoriesMnd + } + trait Mnks extends Job { + val leftSide: LeftSide = BodyMnks + val rightSide: RightSide = AccessoriesStr + } + trait Tanks extends Job { + val leftSide: LeftSide = BodyTanks + val rightSide: RightSide = AccessoriesVit + } + trait Ranges extends Job { + val leftSide: LeftSide = BodyRanges + val rightSide: RightSide = AccessoriesDex + } + + case object PLD extends Tanks + case object WAR extends Tanks + case object DRK extends Tanks + case object GNB extends Tanks + + case object WHM extends Healers + case object SCH extends Healers + case object AST extends Healers + + case object MNK extends Mnks + case object DRG extends Job { + val leftSide: LeftSide = BodyDrgs + val rightSide: RightSide = AccessoriesStr + } + case object NIN extends Job { + val leftSide: LeftSide = BodyNins + val rightSide: RightSide = AccessoriesDex + } + case object SAM extends Mnks + + case object BRD extends Ranges + case object MCH extends Ranges + case object DNC extends Ranges + + case object BLM extends Casters + case object SMN extends Casters + case object RDM extends Casters + + lazy val jobs: Seq[Job] = + Seq(PLD, WAR, DRK, GNB, WHM, SCH, AST, MNK, DRG, NIN, SAM, BRD, MCH, DNC, BLM, SMN, RDM) + + def withName(job: String): Job.Job = jobs.find(_.toString == job.toUpperCase).getOrElse(AnyJob) } diff --git a/src/main/scala/me/arcanis/ffxivbis/service/Party.scala b/src/main/scala/me/arcanis/ffxivbis/models/Party.scala similarity index 79% rename from src/main/scala/me/arcanis/ffxivbis/service/Party.scala rename to src/main/scala/me/arcanis/ffxivbis/models/Party.scala index fcdeb67..9090f76 100644 --- a/src/main/scala/me/arcanis/ffxivbis/service/Party.scala +++ b/src/main/scala/me/arcanis/ffxivbis/models/Party.scala @@ -6,20 +6,18 @@ * * License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause */ -package me.arcanis.ffxivbis.service +package me.arcanis.ffxivbis.models import com.typesafe.config.Config import com.typesafe.scalalogging.StrictLogging -import me.arcanis.ffxivbis.models.{BiS, Loot, Piece, Player, PlayerId} +import me.arcanis.ffxivbis.service.LootSelector import scala.jdk.CollectionConverters._ import scala.util.Random -case class Party(partyId: String, config: Config, players: Map[PlayerId, Player]) +case class Party(partyId: String, rules: Seq[String], players: Map[PlayerId, Player]) extends StrictLogging { - - private val rules = - config.getStringList("me.arcanis.ffxivbis.settings.priority").asScala.toSeq + require(players.keys.forall(_.partyId == partyId), "party id must be same") def getPlayers: Seq[Player] = players.values.toSeq def player(playerId: PlayerId): Option[Player] = players.get(playerId) @@ -38,8 +36,11 @@ case class Party(partyId: String, config: Config, players: Map[PlayerId, Player] } object Party { + private def getRules(config: Config): Seq[String] = + config.getStringList("me.arcanis.ffxivbis.settings.priority").asScala.toSeq + def apply(partyId: Option[String], config: Config): Party = - new Party(partyId.getOrElse(randomPartyId), config, Map.empty) + new Party(partyId.getOrElse(randomPartyId), getRules(config), Map.empty) def apply(partyId: String, config: Config, players: Map[Long, Player], bis: Seq[Loot], loot: Seq[Loot]): Party = { @@ -51,7 +52,7 @@ object Party { .withBiS(bisByPlayer.get(playerId)) .withLoot(lootByPlayer.get(playerId))) } - Party(partyId, config, playersWithItems) + Party(partyId, getRules(config), playersWithItems) } def randomPartyId: String = Random.alphanumeric.take(20).mkString diff --git a/src/main/scala/me/arcanis/ffxivbis/models/Piece.scala b/src/main/scala/me/arcanis/ffxivbis/models/Piece.scala index 73f4ab1..8c235f4 100644 --- a/src/main/scala/me/arcanis/ffxivbis/models/Piece.scala +++ b/src/main/scala/me/arcanis/ffxivbis/models/Piece.scala @@ -104,7 +104,7 @@ object Piece { case other => throw new Error(s"Unknown item type $other") } - def available: Seq[String] = Seq("weapon", + lazy val available: Seq[String] = Seq("weapon", "head", "body", "hands", "waist", "legs", "feet", "ears", "neck", "wrist", "leftRing", "rightRing") } diff --git a/src/main/scala/me/arcanis/ffxivbis/models/Player.scala b/src/main/scala/me/arcanis/ffxivbis/models/Player.scala index bc985a8..acef4c1 100644 --- a/src/main/scala/me/arcanis/ffxivbis/models/Player.scala +++ b/src/main/scala/me/arcanis/ffxivbis/models/Player.scala @@ -15,7 +15,7 @@ case class Player(partyId: String, loot: Seq[Piece], link: Option[String] = None, priority: Int = 0) { - require(job != Job.AnyJob, "AnyJob is not allowed") + require(job ne Job.AnyJob, "AnyJob is not allowed") val playerId: PlayerId = PlayerId(partyId, job, nick) def withBiS(set: Option[BiS]): Player = set match { diff --git a/src/main/scala/me/arcanis/ffxivbis/models/PlayerId.scala b/src/main/scala/me/arcanis/ffxivbis/models/PlayerId.scala index 876e6c2..6e2ad7b 100644 --- a/src/main/scala/me/arcanis/ffxivbis/models/PlayerId.scala +++ b/src/main/scala/me/arcanis/ffxivbis/models/PlayerId.scala @@ -23,13 +23,13 @@ case class PlayerId(partyId: String, job: Job.Job, nick: String) extends PlayerI 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.fromString(job), nick)).toOption + case (Some(nick), Some(job)) => Try(PlayerId(partyId, Job.withName(job), nick)).toOption case _ => None } private val prettyPlayerIdRegex: Regex = "^(.*) \\(([A-Z]{3})\\)$".r def apply(partyId: String, player: String): Option[PlayerId] = player match { - case s"${prettyPlayerIdRegex(nick, job)}" => Try(PlayerId(partyId, Job.fromString(job), nick)).toOption + case s"${prettyPlayerIdRegex(nick, job)}" => Try(PlayerId(partyId, Job.withName(job), nick)).toOption case _ => None } } diff --git a/src/main/scala/me/arcanis/ffxivbis/service/Database.scala b/src/main/scala/me/arcanis/ffxivbis/service/Database.scala index 79f9060..faa0db2 100644 --- a/src/main/scala/me/arcanis/ffxivbis/service/Database.scala +++ b/src/main/scala/me/arcanis/ffxivbis/service/Database.scala @@ -10,7 +10,7 @@ package me.arcanis.ffxivbis.service import akka.actor.Actor import com.typesafe.scalalogging.StrictLogging -import me.arcanis.ffxivbis.models.{Player, PlayerId} +import me.arcanis.ffxivbis.models.{Party, Player, PlayerId} import me.arcanis.ffxivbis.storage.DatabaseProfile import scala.concurrent.{ExecutionContext, Future} diff --git a/src/main/scala/me/arcanis/ffxivbis/storage/BiSProfile.scala b/src/main/scala/me/arcanis/ffxivbis/storage/BiSProfile.scala index eaceabb..580fef1 100644 --- a/src/main/scala/me/arcanis/ffxivbis/storage/BiSProfile.scala +++ b/src/main/scala/me/arcanis/ffxivbis/storage/BiSProfile.scala @@ -17,7 +17,7 @@ trait BiSProfile { this: DatabaseProfile => import dbConfig.profile.api._ case class BiSRep(playerId: Long, created: Long, piece: String, isTome: Int, job: String) { - def toLoot: Loot = Loot(playerId, Piece(piece, isTome == 1, Job.fromString(job))) + def toLoot: Loot = Loot(playerId, Piece(piece, isTome == 1, Job.withName(job))) } object BiSRep { def fromPiece(playerId: Long, piece: Piece) = diff --git a/src/main/scala/me/arcanis/ffxivbis/storage/LootProfile.scala b/src/main/scala/me/arcanis/ffxivbis/storage/LootProfile.scala index b395872..03de0b0 100644 --- a/src/main/scala/me/arcanis/ffxivbis/storage/LootProfile.scala +++ b/src/main/scala/me/arcanis/ffxivbis/storage/LootProfile.scala @@ -18,7 +18,7 @@ trait LootProfile { this: DatabaseProfile => case class LootRep(lootId: Option[Long], playerId: Long, created: Long, piece: String, isTome: Int, job: String) { - def toLoot: Loot = Loot(playerId, Piece(piece, isTome == 1, Job.fromString(job))) + def toLoot: Loot = Loot(playerId, Piece(piece, isTome == 1, Job.withName(job))) } object LootRep { def fromPiece(playerId: Long, piece: Piece) = diff --git a/src/main/scala/me/arcanis/ffxivbis/storage/PlayersProfile.scala b/src/main/scala/me/arcanis/ffxivbis/storage/PlayersProfile.scala index 6fd4079..c723e8a 100644 --- a/src/main/scala/me/arcanis/ffxivbis/storage/PlayersProfile.scala +++ b/src/main/scala/me/arcanis/ffxivbis/storage/PlayersProfile.scala @@ -19,7 +19,7 @@ trait PlayersProfile { this: DatabaseProfile => case class PlayerRep(partyId: String, playerId: Option[Long], created: Long, nick: String, job: String, link: Option[String], priority: Int) { def toPlayer: Player = - Player(partyId, Job.fromString(job), nick, BiS(Seq.empty), List.empty, link, priority) + Player(partyId, Job.withName(job), nick, BiS(Seq.empty), List.empty, link, priority) } object PlayerRep { def fromPlayer(player: Player, id: Option[Long]): PlayerRep = diff --git a/src/test/scala/me/arcanis/ffxivbis/models/BiSTest.scala b/src/test/scala/me/arcanis/ffxivbis/models/BiSTest.scala new file mode 100644 index 0000000..cd789ce --- /dev/null +++ b/src/test/scala/me/arcanis/ffxivbis/models/BiSTest.scala @@ -0,0 +1,55 @@ +package me.arcanis.ffxivbis.models + +import me.arcanis.ffxivbis.utils.Compare +import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} + +class BiSTest extends WordSpecLike with Matchers with BeforeAndAfterAll { + + "bis model" must { + + "build set from list" in { + BiS(Fixtures.bis.pieces) shouldEqual Fixtures.bis + } + + "has piece" in { + Fixtures.bis.hasPiece(Fixtures.lootBody) shouldEqual true + Fixtures.bis.hasPiece(Fixtures.lootHands) shouldEqual true + } + + "has upgrade" in { + Fixtures.bis.hasPiece(Fixtures.lootUpgrade) shouldEqual true + } + + "does not have piece" in { + Fixtures.bis.hasPiece(Fixtures.lootLegs) shouldEqual false + } + + "create copy with another piece" in { + 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 + } + + "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 + } + + "ignore upgrade on modification" in { + Fixtures.bis.withPiece(Fixtures.lootUpgrade) shouldEqual Fixtures.bis + Fixtures.bis.withoutPiece(Fixtures.lootUpgrade) shouldEqual Fixtures.bis + } + + "return upgrade list" in { + Compare.mapEquals(Fixtures.bis.upgrades, Map[PieceUpgrade, Int](BodyUpgrade -> 2, AccessoryUpgrade -> 4)) shouldEqual true + } + + } +} diff --git a/src/test/scala/me/arcanis/ffxivbis/models/Fixtures.scala b/src/test/scala/me/arcanis/ffxivbis/models/Fixtures.scala index ab09eee..5f79c84 100644 --- a/src/test/scala/me/arcanis/ffxivbis/models/Fixtures.scala +++ b/src/test/scala/me/arcanis/ffxivbis/models/Fixtures.scala @@ -1,7 +1,5 @@ package me.arcanis.ffxivbis.models -import me.arcanis.ffxivbis.service.Party - object Fixtures { lazy val bis: BiS = BiS( Seq( @@ -22,9 +20,15 @@ object Fixtures { lazy val link: String = "https://ffxiv.ariyala.com/19V5R" - lazy val lootBody: Piece = Body(isTome = false, Job.DNC) - lazy val lootHands: Piece = Hands(isTome = true, Job.DNC) - lazy val lootLegs: Piece = Legs(isTome = false, Job.DNC) + lazy val lootWeapon: Piece = Weapon(isTome = true, Job.AnyJob) + lazy val lootBody: Piece = Body(isTome = false, Job.AnyJob) + lazy val lootHands: Piece = Hands(isTome = true, Job.AnyJob) + lazy val lootWaist: Piece = Waist(isTome = true, Job.AnyJob) + lazy val lootLegs: Piece = Legs(isTome = false, Job.AnyJob) + lazy val lootEars: Piece = Ears(isTome = false, Job.AnyJob) + lazy val lootRing: Piece = Ring(isTome = true, Job.AnyJob) + lazy val lootLeftRing: Piece = Ring(isTome = true, Job.AnyJob, "leftRing") + lazy val lootRightRing: Piece = Ring(isTome = true, Job.AnyJob, "rightRing") lazy val lootUpgrade: Piece = BodyUpgrade lazy val loot: Seq[Piece] = Seq(lootBody, lootHands, lootLegs, lootUpgrade) diff --git a/src/test/scala/me/arcanis/ffxivbis/models/JobTest.scala b/src/test/scala/me/arcanis/ffxivbis/models/JobTest.scala new file mode 100644 index 0000000..981629d --- /dev/null +++ b/src/test/scala/me/arcanis/ffxivbis/models/JobTest.scala @@ -0,0 +1,26 @@ +package me.arcanis.ffxivbis.models + +import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} + +class JobTest extends WordSpecLike with Matchers with BeforeAndAfterAll { + + "job model" must { + + "create job from string" in { + Job.jobs.foreach { job => + Job.withName(job.toString) shouldEqual job + } + } + + "return AnyJob on unknown job" in { + Job.withName("random string") shouldEqual Job.AnyJob + } + + "equal AnyJob to others" in { + Job.jobs.foreach { job => + Job.AnyJob shouldBe job + } + } + + } +} diff --git a/src/test/scala/me/arcanis/ffxivbis/models/PartyTest.scala b/src/test/scala/me/arcanis/ffxivbis/models/PartyTest.scala new file mode 100644 index 0000000..4ffba03 --- /dev/null +++ b/src/test/scala/me/arcanis/ffxivbis/models/PartyTest.scala @@ -0,0 +1,51 @@ +package me.arcanis.ffxivbis.models + +import me.arcanis.ffxivbis.utils.Compare +import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} + +class PartyTest extends WordSpecLike with Matchers with BeforeAndAfterAll { + + private val party = + Party(Fixtures.partyId, 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)) + } + + "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)) + an [IllegalArgumentException] should be thrownBy + Party(Fixtures.partyId, Seq.empty, Map(Fixtures.playerEmpty.playerId -> Fixtures.playerEmpty, anotherPlayer.playerId -> anotherPlayer)) + } + + "return player list" in { + Compare.seqEquals(party.getPlayers, Seq(Fixtures.playerEmpty)) shouldEqual true + } + + "return player" in { + party.player(Fixtures.playerEmpty.playerId) shouldEqual Some(Fixtures.playerEmpty) + } + + "return empty on unknown player" in { + party.player(Fixtures.playerEmpty.copy(partyId = Fixtures.partyId2).playerId) shouldEqual None + } + + "add new player" in { + val newParty = Party(Fixtures.partyId, Seq.empty, Map.empty) + newParty.withPlayer(Fixtures.playerEmpty) shouldEqual party + } + + "reject player with another party id" in { + val anotherPlayer = Fixtures.playerEmpty.copy(partyId = Fixtures.partyId2) + + party.withPlayer(anotherPlayer) shouldEqual party + } + + } +} diff --git a/src/test/scala/me/arcanis/ffxivbis/models/PieceTest.scala b/src/test/scala/me/arcanis/ffxivbis/models/PieceTest.scala new file mode 100644 index 0000000..522fc17 --- /dev/null +++ b/src/test/scala/me/arcanis/ffxivbis/models/PieceTest.scala @@ -0,0 +1,32 @@ +package me.arcanis.ffxivbis.models + +import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} + +class PieceTest extends WordSpecLike with Matchers with BeforeAndAfterAll { + + "piece model" must { + + "convert `isTome` property to string" in { + Fixtures.lootBody.isTomeToString shouldEqual "no" + Fixtures.lootHands.isTomeToString shouldEqual "yes" + } + + "return upgrade" in { + Fixtures.lootWeapon.upgrade shouldEqual Some(WeaponUpgrade) + Fixtures.lootBody.upgrade shouldEqual None + Fixtures.lootHands.upgrade shouldEqual Some(BodyUpgrade) + Fixtures.lootWaist.upgrade shouldEqual Some(AccessoryUpgrade) + Fixtures.lootLegs.upgrade shouldEqual None + Fixtures.lootEars.upgrade shouldEqual None + Fixtures.lootLeftRing.upgrade shouldEqual Some(AccessoryUpgrade) + Fixtures.lootRightRing.upgrade shouldEqual Some(AccessoryUpgrade) + } + + "build piece from string" in { + Fixtures.bis.pieces.foreach { piece => + Piece(piece.piece, piece.isTome, piece.job) shouldEqual piece + } + } + + } +} diff --git a/src/test/scala/me/arcanis/ffxivbis/models/PlayerIdTest.scala b/src/test/scala/me/arcanis/ffxivbis/models/PlayerIdTest.scala new file mode 100644 index 0000000..8f3e07f --- /dev/null +++ b/src/test/scala/me/arcanis/ffxivbis/models/PlayerIdTest.scala @@ -0,0 +1,14 @@ +package me.arcanis.ffxivbis.models + +import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} + +class PlayerIdTest extends WordSpecLike with Matchers with BeforeAndAfterAll { + + "player id model" must { + + "be parsed from string" in { + PlayerId(Fixtures.partyId, Fixtures.playerEmpty.playerId.toString) shouldEqual Some(Fixtures.playerEmpty.playerId) + } + + } +} diff --git a/src/test/scala/me/arcanis/ffxivbis/models/PlayerTest.scala b/src/test/scala/me/arcanis/ffxivbis/models/PlayerTest.scala new file mode 100644 index 0000000..6f6035a --- /dev/null +++ b/src/test/scala/me/arcanis/ffxivbis/models/PlayerTest.scala @@ -0,0 +1,18 @@ +package me.arcanis.ffxivbis.models + +import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} + +class PlayerTest extends WordSpecLike with Matchers with BeforeAndAfterAll { + + "player model" must { + + "add best in slot set" in { + Fixtures.playerEmpty.withBiS(Some(Fixtures.bis)).bis shouldEqual Fixtures.bis + } + + "add loot" in { + Fixtures.playerEmpty.withLoot(Some(Fixtures.loot)).loot shouldEqual Fixtures.loot + } + + } +} diff --git a/src/test/scala/me/arcanis/ffxivbis/models/UserTest.scala b/src/test/scala/me/arcanis/ffxivbis/models/UserTest.scala new file mode 100644 index 0000000..f0911c9 --- /dev/null +++ b/src/test/scala/me/arcanis/ffxivbis/models/UserTest.scala @@ -0,0 +1,24 @@ +package me.arcanis.ffxivbis.models + +import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} + +class UserTest extends WordSpecLike with Matchers with BeforeAndAfterAll { + + "user model" must { + + "verify password" in { + Fixtures.userAdmin.verify(Fixtures.userPassword) shouldEqual true + Fixtures.userAdmin.verify(Fixtures.userPassword2) shouldEqual false + } + + "verify scope" in { + Permission.values.foreach { permission => + Fixtures.userAdmin.verityScope(permission) shouldEqual true + } + Permission.values.foreach { permission => + Fixtures.userGet.verityScope(permission) shouldEqual (permission == Permission.get) + } + } + + } +} diff --git a/src/test/scala/me/arcanis/ffxivbis/service/DatabasePartyHandlerTest.scala b/src/test/scala/me/arcanis/ffxivbis/service/DatabasePartyHandlerTest.scala index 75c5451..5727f55 100644 --- a/src/test/scala/me/arcanis/ffxivbis/service/DatabasePartyHandlerTest.scala +++ b/src/test/scala/me/arcanis/ffxivbis/service/DatabasePartyHandlerTest.scala @@ -2,7 +2,7 @@ package me.arcanis.ffxivbis.service import akka.actor.ActorSystem import akka.testkit.{ImplicitSender, TestKit} -import me.arcanis.ffxivbis.models.{Fixtures, Settings} +import me.arcanis.ffxivbis.models.{Fixtures, Party, Settings} import me.arcanis.ffxivbis.storage.Migration import me.arcanis.ffxivbis.utils.Compare import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} diff --git a/src/test/scala/me/arcanis/ffxivbis/utils/Compare.scala b/src/test/scala/me/arcanis/ffxivbis/utils/Compare.scala index 637aa00..2fb0cea 100644 --- a/src/test/scala/me/arcanis/ffxivbis/utils/Compare.scala +++ b/src/test/scala/me/arcanis/ffxivbis/utils/Compare.scala @@ -1,6 +1,11 @@ package me.arcanis.ffxivbis.utils object Compare { + def mapEquals[K, T](left: Map[K, T], right: Map[K, T]): Boolean = + left.forall { + case (key, value) => right.contains(key) && right(key) == value + } + def seqEquals[T](left: Seq[T], right: Seq[T]): Boolean = left.groupBy(identity).view.mapValues(_.size).forall { case (key, count) => right.count(_ == key) == count