| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- package controllers
- import scala.concurrent.Await
- import scala.concurrent.duration.Duration
- import org.scalatestplus.play._
- import akka.stream.Materializer
- import play.api.mvc._
- import play.api.test._
- import play.api.test.Helpers._
- import play.api.http.Status
- import play.api.http.HeaderNames
- import play.api.libs.json.{JsValue,JsObject,Json}
- import org.scalatest._
- import org.scalatestplus.play._
- import org.scalatestplus.play.guice._
- import com.github.simplyscala.{MongoEmbedDatabase,MongodProps}
- import org.mongodb.scala.{MongoClient,MongoDatabase,MongoCollection,Observer};
- import models.Food
- class FoodControllerSpec
- extends PlaySpec
- with GuiceOneAppPerTest
- with Injecting
- with MongoEmbedDatabase {
- val testDBPort: Int = 12345
- implicit lazy val materializer: Materializer = app.materializer
- def getDBColl(): MongoCollection[Food] = {
- val db: MongoDatabase = MongoClient.apply(s"mongodb://localhost:${testDBPort}")
- .getDatabase("recipes")
- .withCodecRegistry(MongoDB.codecRegistry)
- db.createCollection("Food")
- db.getCollection[Food]("Food")
- }
- // def blockingObserver[T](sem: Semaphore, processor: T => Unit) = new Observer[T] {
- // override def onNext(result: T) = {println("next");processor(result)}
- // override def onError(e: Throwable) = {
- // println("error")
- // sem.release()
- // throw e
- // }
- // override def onComplete() = {println("complete");sem.release()}
- // }
- "FoodController PUT /food" should {
- "return the resulting food object and insert into the DB" in {
- val body: JsValue = Json.parse(
- """{"name": "Example Food",
- |"glutenFree": false,
- |"vegitarian": true,
- |"vegan": false,
- |"nutrients": {"iron": 1.2, "B": 7},
- |"source": "Test Script",
- |"category": ["Breakfast", "Asian"],
- |"primaryMeasure": "mass",
- |"density": 3.2,
- |"mass_p_u": 2.7,
- |"price": 1237,
- |"alternatives": ["Scrambled Eggs"]
- |} """.stripMargin
- )
- val fakeRequ: FakeRequest[JsValue] = FakeRequest[JsValue](PUT, "/food", FakeHeaders(), body)
- .withHeaders(HeaderNames.CONTENT_TYPE -> "application/json")
- withEmbedMongoFixture() { mongodProps: MongodProps =>
- val coll: MongoCollection[Food] = getDBColl
- val controller: FoodController = new FoodController(coll)
- val result = controller.put().apply(fakeRequ)
- status(result) mustBe OK
- contentType(result) mustBe Some("application/json")
- val resultJs: JsObject = contentAsJson(result).asInstanceOf[JsObject]
- resultJs - "_id" mustBe body
- Await.result(coll.countDocuments().toFuture, Duration.Inf) mustBe 1
- Await.result(coll.find().first().toFuture, Duration.Inf) mustBe resultJs.as[Food]
- }
- }
- // Removed: not presenting id's to front-end
- // "return the resulting food object with a distinct id" in {
- // val controller = inject[HomeController]
- // val home = controller.index().apply(FakeRequest(GET, "/"))
- // status(home) mustBe OK
- // contentType(home) mustBe Some("text/html")
- // contentAsString(home) must include ("Welcome to Play")
- // }
- "return an error when given an empty request and not " +
- "insert into the DB" in {
- val fakeRequ = FakeRequest(PUT, "/food", FakeHeaders(), "")
- .withHeaders(HeaderNames.CONTENT_TYPE -> "application/json")
- withEmbedMongoFixture() { mongodProps: MongodProps =>
- val coll: MongoCollection[Food] = getDBColl
- val controller: FoodController = new FoodController(coll)
- val result = controller.put().apply(fakeRequ)
- status(result) mustBe Status.BAD_REQUEST
- Await.result(coll.countDocuments().toFuture, Duration.Inf) mustBe 0
- }
- }
- "return an error when given an invalid request and not " +
- "insert into the DB" in {
- val body: JsValue = Json.parse(// Name intentionally moved
- """{
- |"glutenFree": false,
- |"vegitarian": true,
- |"vegan": false,
- |"nutrients": {"iron": 1.2, "B": 7},
- |"source": "Test Script",
- |"category": ["Breakfast", "Asian"],
- |"primaryMeasure": "mass",
- |"density": 3.2,
- |"mass_p_u": 2.7,
- |"price": 1237,
- |"alternatives": ["Scrambled Eggs"]
- |} """.stripMargin
- )
- val fakeRequ = FakeRequest(PUT, "/food", FakeHeaders(), body)
- .withHeaders(HeaderNames.CONTENT_TYPE -> "application/json")
- withEmbedMongoFixture() { mongodProps: MongodProps =>
- val coll: MongoCollection[Food] = getDBColl
- val controller: FoodController = new FoodController(coll)
- val result = controller.put().apply(fakeRequ)
- status(result) mustBe Status.BAD_REQUEST
- Await.result(coll.countDocuments().toFuture, Duration.Inf) mustBe 0
- }
- }
- "return the resulting object with default values and " +
- "insert into the DB" in {
- val body: JsValue = Json.parse(
- """{"name": "Example Food",
- |"vegitarian": true,
- |"nutrients": {"iron": 1.2, "B": 7},
- |"source": "Test Script",
- |"category": ["Breakfast", "Asian"],
- |"primaryMeasure": "mass",
- |"density": 3.2,
- |"mass_p_u": 2.7,
- |"price": 1237,
- |"alternatives": ["Scrambled Eggs"]
- |} """.stripMargin
- )
- val expected: JsValue = Json.parse(
- """{"name": "Example Food",
- |"glutenFree": false,
- |"vegitarian": true,
- |"vegan": false,
- |"nutrients": {"iron": 1.2, "B": 7},
- |"source": "Test Script",
- |"category": ["Breakfast", "Asian"],
- |"primaryMeasure": "mass",
- |"density": 3.2,
- |"mass_p_u": 2.7,
- |"price": 1237,
- |"alternatives": ["Scrambled Eggs"]
- |} """.stripMargin
- )
- val fakeRequ = FakeRequest(PUT, "/food", FakeHeaders(), body)
- .withHeaders(HeaderNames.CONTENT_TYPE -> "application/json")
- withEmbedMongoFixture() { mongodProps: MongodProps =>
- val coll: MongoCollection[Food] = getDBColl
- val controller: FoodController = new FoodController(coll)
- val result = controller.put().apply(fakeRequ)
- status(result) mustBe OK
- contentType(result) mustBe Some("application/json")
- val resultJs: JsObject = contentAsJson(result).asInstanceOf[JsObject]
- resultJs - "_id" mustBe expected
- Await.result(coll.countDocuments().toFuture, Duration.Inf) mustBe 1
- Await.result(coll.find().first().toFuture, Duration.Inf) mustBe resultJs.as[Food]
- }
- }
- }
- }
|