-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unit & Integration #15
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package com.zeta.playthegame.integration | ||
|
||
import java.util.concurrent.TimeUnit.DAYS | ||
|
||
import cats.effect.IO | ||
import com.zeta.playthegame.model.Sport.FootballFive | ||
import com.zeta.playthegame.model.{Appointment, Game} | ||
import com.zeta.playthegame.repository.AppointmentsRepository | ||
import com.zeta.playthegame.util.Generators | ||
import com.zeta.playthegame.{AppointmentRequest, AppointmentsRoutes} | ||
import io.circe.Json | ||
import io.circe.generic.auto._ | ||
import io.circe.syntax._ | ||
import org.http4s.circe._ | ||
import org.http4s.client.blaze.BlazeClientBuilder | ||
import org.http4s.{HttpRoutes, Method, Request, Uri} | ||
import org.scalatest.{FlatSpecLike, Matchers} | ||
|
||
import scala.concurrent.ExecutionContext.Implicits.global | ||
|
||
class AppointmentsIT extends FlatSpecLike | ||
with Matchers | ||
with Generators | ||
with ServerApp | ||
with MongoManager { | ||
|
||
import RequestUtils._ | ||
|
||
private val testRepository = new AppointmentsRepository(MongoTestConnection)(global) | ||
override val router: HttpRoutes[IO] = new AppointmentsRoutes(testRepository).routes | ||
|
||
override def beforeAll() = { | ||
tearDown.unsafeRunSync() | ||
startServer | ||
} | ||
|
||
override def afterAll() = stopServer | ||
|
||
"POST and Retrieve appointment" should "success" in { | ||
val authorId = randomStringId | ||
val createdDate = millisNow | ||
val appointmentDate = millisNowPlus(2, DAYS) | ||
val requestBody = AppointmentRequest( | ||
authorId, | ||
appointmentDate, | ||
createdDate, | ||
Game(FootballFive, List(randomStringId))).asJson | ||
|
||
val postRequest = post(baseUri / "appointments", requestBody) | ||
val maybeCreatedAppointment = response(postRequest).unsafeRunSync().as[Appointment] | ||
maybeCreatedAppointment shouldBe 'right | ||
val createdGameAppointment = maybeCreatedAppointment.right.get | ||
|
||
createdGameAppointment.authorId shouldBe authorId | ||
createdGameAppointment.appointmentDate shouldBe appointmentDate | ||
createdGameAppointment.createdDate shouldBe createdDate | ||
createdGameAppointment.game.sport shouldBe FootballFive | ||
|
||
val getRequest = get(baseUri / "appointments" / createdGameAppointment.appointmentId) | ||
val maybeRetrievedAppointment = response(getRequest).unsafeRunSync().as[Appointment] | ||
maybeRetrievedAppointment shouldBe 'right | ||
val retrievedGameAppointment = maybeCreatedAppointment.right.get | ||
|
||
retrievedGameAppointment shouldBe createdGameAppointment | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Se me hace que los tests deberiamos escribirlos de forma funcional tambien. for {
...
createdAppointment <- response(postRequest)
...
retrievedAppointment <- response(getRequest)
} yield createdAppointment shouldBe retrievedAppointment que todo eso devuelva Tambien aca tiene mas sentido NO usar either u option ademas de IO. Que el |
||
|
||
object RequestUtils { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. esto en algun momento va a terminar siendo un DSL cross para todos los IT |
||
|
||
def request(uri: Uri, method: Method) = Request[IO](method, uri) | ||
|
||
def post(uri: Uri) = request(uri, Method.POST) | ||
|
||
def post(uri: Uri, body: Json): Request[IO] = request(uri, Method.POST).withEntity(body) | ||
|
||
def get(uri: Uri) = request(uri, Method.GET) | ||
|
||
def response(request: Request[IO]) = BlazeClientBuilder[IO](global).resource.use(_.expect[Json](request)) | ||
|
||
def status(request: Request[IO]) = BlazeClientBuilder[IO](global).resource.use(_.status(request)) | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.zeta.playthegame.integration | ||
|
||
import cats.effect.IO | ||
import com.zeta.playthegame.repository.Codecs.codecRegistry | ||
import com.zeta.playthegame.repository.{Entities, MongoConnection} | ||
import com.zeta.playthegame.util.IOExt._ | ||
import org.mongodb.scala.{MongoCollection, MongoDatabase} | ||
|
||
trait MongoManager { | ||
import MongoTestConnection._ | ||
|
||
def tearDown = database.map(_.drop().head()) toIO | ||
} | ||
|
||
object MongoTestConnection extends MongoConnection { | ||
override val databaseName: String = "test" | ||
val appointmentsCollectionName = "appointments" | ||
override val database: IO[MongoDatabase] = mongoClient.map(_.getDatabase("test").withCodecRegistry(codecRegistry)) | ||
override val appointmentsCollection: IO[MongoCollection[Entities.AppointmentDocument]] = database.map(_.getCollection(appointmentsCollectionName)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.zeta.playthegame.integration | ||
|
||
import cats.effect.{ContextShift, Fiber, IO, Timer} | ||
import org.http4s.{HttpRoutes, Uri} | ||
import org.http4s.implicits._ | ||
import org.http4s.server.blaze.BlazeServerBuilder | ||
import org.scalatest.{BeforeAndAfterAll, TestSuite} | ||
|
||
trait ServerApp extends BeforeAndAfterAll { self: TestSuite => | ||
|
||
implicit val ec = scala.concurrent.ExecutionContext.Implicits.global | ||
implicit val cs: ContextShift[IO] = IO.contextShift(ec) | ||
implicit val timer: Timer[IO] = IO.timer(ec) | ||
|
||
val baseUri = Uri.unsafeFromString("http://localhost:8080") | ||
val router: HttpRoutes[IO] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. La idea es cada IT extienda este trait y define el There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bueni pero agregame pure config. |
||
var serverTask: Fiber[IO, Nothing] = _ | ||
|
||
private def createServer = { | ||
BlazeServerBuilder[IO] | ||
.bindHttp(8080, "0.0.0.0") | ||
.withHttpApp(router.orNotFound) | ||
} | ||
|
||
def startServer = serverTask = createServer.resource.use(_ => IO.never).start.unsafeRunSync() | ||
|
||
def stopServer = serverTask.cancel | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.zeta.playthegame.model | ||
|
||
import java.util.concurrent.TimeUnit.DAYS | ||
|
||
import com.zeta.playthegame.model.Sport.{FootballFive, TennisSingle} | ||
import com.zeta.playthegame.util.Generators | ||
import org.scalatest.{FlatSpecLike, Matchers} | ||
|
||
class GameSpec extends FlatSpecLike with Matchers with Generators { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No veo que uses ningun |
||
|
||
val zeta = randomStringId | ||
val palan = randomStringId | ||
val footballFive = Game(FootballFive, List(zeta)) | ||
val appointment = Appointment(randomStringId, zeta, millisNowPlus(2, DAYS), millisNow, footballFive) | ||
|
||
it should "Add Players to appointment" in { | ||
appointment.getPlayers.size shouldBe 1 | ||
val updatedAppointment = appointment.addPlayer(palan) | ||
updatedAppointment.getPlayers.size shouldBe 2 | ||
updatedAppointment.getPlayers should contain theSameElementsAs List(zeta, palan) | ||
} | ||
|
||
it should "Delete Players of appointment" in { | ||
val updatedAppointment = appointment.removePlayer(zeta) | ||
updatedAppointment.getPlayers.size shouldBe 0 | ||
} | ||
|
||
it should "Change author of appointment" in { | ||
val palan = randomStringId | ||
appointment.authorId shouldBe zeta | ||
val updatedAppointment = appointment.changeAuthor(palan) | ||
updatedAppointment.authorId shouldBe palan | ||
} | ||
|
||
it should "Change appointment date" in { | ||
val updated = appointment.changeAppointmentDate(millisNowPlus(4, DAYS)) | ||
updated.appointmentDate should be > appointment.appointmentDate | ||
} | ||
|
||
it should "Change Sport" in { | ||
val updated = appointment.changeSport(TennisSingle) | ||
updated.sport shouldBe TennisSingle | ||
} | ||
|
||
it should "Set a result" in { | ||
val updated = appointment.addPlayer(palan) | ||
.changeSport(TennisSingle) | ||
.addResult(Result(List(palan), List(zeta), 3, 2)) | ||
|
||
updated.winner shouldBe 'defined | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sameeeeeeee |
||
updated.loser shouldBe 'defined | ||
|
||
updated.winner.get should contain theSameElementsAs List(palan) | ||
updated.loser.get should contain theSameElementsAs List(zeta) | ||
|
||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
horrible como se ve en github, pero bueno es la forma que sugiere la docu de ScalaTest para verificar el tipo de Either 🤷♂